Skip to content

Commit 9ace39a

Browse files
LocalIdentityLocalIdentity
andauthored
Memoize MatchKeywordFlags function (#1507)
This function gets called on every Sum, More, Flag, Override, List and Tabulate call so ends up being called hundreds of thousands of times when running the gem DPS sort and also a lot when running the tree node sort At the start of each initEnv we have a fresh cache and store each unique Keyword flag match so it can quickly be used in a lookup instead of computed over and over again saving a ton of band calls Co-authored-by: LocalIdentity <localidentity2@gmail.com>
1 parent 2aa9170 commit 9ace39a

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

src/Data/Global.lua

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,17 +292,44 @@ KeywordFlag.MatchAll = 0x40000000
292292
local band = AND64
293293
local bnot = NOT64
294294
local MatchAllMask = bnot(KeywordFlag.MatchAll)
295+
296+
-- Two-level numeric-key cache to avoid building string keys or allocating tables per call.
297+
local matchKeywordFlagsCache = {}
298+
function ClearMatchKeywordFlagsCache()
299+
-- cheap full reset without reallocating the outer table
300+
for k in pairs(matchKeywordFlagsCache) do
301+
matchKeywordFlagsCache[k] = nil
302+
end
303+
end
304+
295305
---@param keywordFlags number The KeywordFlags to be compared to.
296306
---@param modKeywordFlags number The KeywordFlags stored in the mod.
297307
---@return boolean Whether the KeywordFlags in the mod are satisfied.
298308
function MatchKeywordFlags(keywordFlags, modKeywordFlags)
309+
-- Cache lookup
310+
local row = matchKeywordFlagsCache[keywordFlags]
311+
if row then
312+
local cached = row[modKeywordFlags]
313+
if cached ~= nil then
314+
return cached
315+
end
316+
else
317+
row = {}
318+
matchKeywordFlagsCache[keywordFlags] = row
319+
end
320+
-- Not in cache, compute normally
299321
local matchAll = band(modKeywordFlags, KeywordFlag.MatchAll) ~= 0
300-
modKeywordFlags = band(modKeywordFlags, MatchAllMask)
301-
keywordFlags = band(keywordFlags, MatchAllMask)
322+
local modMasked = band(modKeywordFlags, MatchAllMask)
323+
local keywordMasked = band(keywordFlags, MatchAllMask)
324+
325+
local matches
302326
if matchAll then
303-
return band(keywordFlags, modKeywordFlags) == modKeywordFlags
327+
matches = band(keywordMasked, modMasked) == modMasked
328+
else
329+
matches = (modMasked == 0) or (band(keywordMasked, modMasked) ~= 0)
304330
end
305-
return modKeywordFlags == 0 or band(keywordFlags, modKeywordFlags) ~= 0
331+
row[modKeywordFlags] = matches -- Add to cache
332+
return matches
306333
end
307334

308335
-- Active skill types, used in ActiveSkills.dat and GrantedEffects.dat

src/Modules/CalcSetup.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ end
481481
-- 5. Builds a list of active skills and their supports (calcs.createActiveSkill)
482482
-- 6. Builds modifier lists for all active skills (calcs.buildActiveSkillModList)
483483
function calcs.initEnv(build, mode, override, specEnv)
484+
ClearMatchKeywordFlagsCache()
484485
-- accelerator variables
485486
local cachedPlayerDB = specEnv and specEnv.cachedPlayerDB or nil
486487
local cachedEnemyDB = specEnv and specEnv.cachedEnemyDB or nil

0 commit comments

Comments
 (0)