perf: optimize spell and unit ID lookups with caching and fix range cache memory leaks

This commit is contained in:
Bluewhale1337
2026-10-02 12:17:29 +02:00
parent f4ba0d983d
commit 032c7571af
6 changed files with 64 additions and 43 deletions
+30 -17
View File
@@ -240,25 +240,38 @@ end
local HealBot_RaidUnitTokens = {} local HealBot_RaidUnitTokens = {}
for i=1, 40 do HealBot_RaidUnitTokens[i] = "raid"..i end for i=1, 40 do HealBot_RaidUnitTokens[i] = "raid"..i end
HealBot_NameToUnitID = {}
function HealBot_UpdateUnitIDCache()
HealBot_NameToUnitID = {}
local name = UnitName("player")
if name then HealBot_NameToUnitID[name] = "player" end
for i=1, 4 do
local unit = "party"..i
name = UnitName(unit)
if name then HealBot_NameToUnitID[name] = unit end
unit = "partypet"..i
name = UnitName(unit)
if name then HealBot_NameToUnitID[name] = unit end
end
local petName = UnitName("pet")
if petName then HealBot_NameToUnitID[petName] = "pet" end
for i=1, 40 do
local unit = "raid"..i
name = UnitName(unit)
if name then HealBot_NameToUnitID[name] = unit end
unit = "raidpet"..i
name = UnitName(unit)
if name then HealBot_NameToUnitID[name] = unit end
end
end
-- HealBot_FindUnitID: Finds a unit token for a given player name. -- HealBot_FindUnitID: Finds a unit token for a given player name.
function HealBot_FindUnitID(unitname) function HealBot_FindUnitID(unitname)
local text; return HealBot_NameToUnitID[unitname]
if HealBot_Action_HealGroup then
for _,unit in ipairs(HealBot_Action_HealGroup) do
text = UnitName(unit);
if text and text==unitname then
return unit;
end
end
end
for i=1,40 do
local unit = HealBot_RaidUnitTokens[i];
text = UnitName(unit);
if text and text==unitname then
return unit;
end
end
return nil;
end end
-- HealBot_PlaySound: Plays an audio alert based on ID. -- HealBot_PlaySound: Plays an audio alert based on ID.
+2
View File
@@ -498,6 +498,7 @@ end
function HealBot_OnEvent_PartyMembersChanged(this) function HealBot_OnEvent_PartyMembersChanged(this)
HealBot_Model:PreserveStateByGUID() HealBot_Model:PreserveStateByGUID()
HealBot_Integrations_PruneNampower() HealBot_Integrations_PruneNampower()
if HealBot_UpdateUnitIDCache then HealBot_UpdateUnitIDCache() end
if HealBot_IsFighting then if HealBot_IsFighting then
HealBot_Action_PartyChanged() HealBot_Action_PartyChanged()
end end
@@ -557,6 +558,7 @@ end
function HealBot_OnEvent_SpellsChanged(this, arg1) function HealBot_OnEvent_SpellsChanged(this, arg1)
if arg1 then return; end if arg1 then return; end
HealBot_AddDebug("HB: SpellsChanged"); HealBot_AddDebug("HB: SpellsChanged");
if HealBot_CacheSpellIDs then HealBot_CacheSpellIDs() end
HealBot_SpellsInitFlag = 2; HealBot_SpellsInitFlag = 2;
end end
+9 -5
View File
@@ -15,7 +15,11 @@ local _lastFrameTime = 0
function HealBot_Range_Check(unit, range) function HealBot_Range_Check(unit, range)
local currentTime = GetTime() local currentTime = GetTime()
if _lastFrameTime ~= currentTime then if _lastFrameTime ~= currentTime then
for k in pairs(_rangeCache) do _rangeCache[k] = nil end for r, cacheTable in pairs(_rangeCache) do
for u in pairs(cacheTable) do
cacheTable[u] = nil
end
end
_lastFrameTime = currentTime _lastFrameTime = currentTime
end end
@@ -24,9 +28,9 @@ function HealBot_Range_Check(unit, range)
range = 40; range = 40;
end end
local cacheKey = unit .. "_" .. range _rangeCache[range] = _rangeCache[range] or {}
if _rangeCache[cacheKey] ~= nil then if _rangeCache[range][unit] ~= nil then
return _rangeCache[cacheKey] return _rangeCache[range][unit]
end end
if ( unit == "player" ) then if ( unit == "player" ) then
@@ -72,6 +76,6 @@ function HealBot_Range_Check(unit, range)
end end
end end
_rangeCache[cacheKey] = return_val _rangeCache[range][unit] = return_val
return return_val; return return_val;
end end
+18 -20
View File
@@ -34,28 +34,26 @@ function HealBot_GetSpellName(id)
return spellName .. " (" .. subSpellName .. ")"; return spellName .. " (" .. subSpellName .. ")";
end end
HealBot_SpellNameToId = {}
function HealBot_CacheSpellIDs()
HealBot_SpellNameToId = {}
local id = 1
while true do
local spellName, subSpellName = GetSpellName(id, BOOKTYPE_SPELL)
if not spellName then break end
if subSpellName and subSpellName ~= "" then
HealBot_SpellNameToId[spellName .. " (" .. subSpellName .. ")"] = id
HealBot_SpellNameToId[spellName .. "(" .. subSpellName .. ")"] = id
end
HealBot_SpellNameToId[spellName] = id
id = id + 1
end
end
-- HealBot_GetSpellId: Internal utility: HealBot_GetSpellId -- HealBot_GetSpellId: Internal utility: HealBot_GetSpellId
function HealBot_GetSpellId(spell) function HealBot_GetSpellId(spell)
local id, idd = 1, 0; return HealBot_SpellNameToId[spell]
while true do
local spellName, subSpellName = GetSpellName(id, BOOKTYPE_SPELL);
if (spellName) then
if (spell == spellName .. " (" .. subSpellName .. ")") or (spell == spellName .. "(" .. subSpellName .. ")") then
return id;
end
if (spell == spellName) then
idd = id;
end
else
break
end
id = id + 1;
end
if idd > 0 then
return idd
else
return nil;
end
end end
-- HealBot_CastSpellByName: Internal utility: HealBot_CastSpellByName -- HealBot_CastSpellByName: Internal utility: HealBot_CastSpellByName
-1
View File
@@ -21,7 +21,6 @@ function HealBot_Integrations_Toggle()
HealBot_Integrations_UnitXP_Active = true; HealBot_Integrations_UnitXP_Active = true;
HealBot_AddDebug("UnitXP Integration: ENABLED"); HealBot_AddDebug("UnitXP Integration: ENABLED");
else else
Look at the lines that need translation
HealBot_Integrations_UnitXP_Active = false; HealBot_Integrations_UnitXP_Active = false;
HealBot_AddDebug("UnitXP Integration: DISABLED"); HealBot_AddDebug("UnitXP Integration: DISABLED");
end end
+5
View File
@@ -152,6 +152,11 @@ Default installation path: `C:\Program Files\World of Warcraft\Interface\AddOns\
* **Chat Announcements & Mouseover Casts:** Chat announcements are now correctly fired when using native Hovercasting (Mouseover). Additionally, added safety checks to prevent spamming chat announcements when accidentally clicking on a dead player (unless casting a resurrection spell). * **Chat Announcements & Mouseover Casts:** Chat announcements are now correctly fired when using native Hovercasting (Mouseover). Additionally, added safety checks to prevent spamming chat announcements when accidentally clicking on a dead player (unless casting a resurrection spell).
* **New Priest Buff (Enlighten):** Added the custom "Enlighten" buff to Priest trackable buffs, complete with the `btnholyscriptures` icon on unit frames. * **New Priest Buff (Enlighten):** Added the custom "Enlighten" buff to Priest trackable buffs, complete with the `btnholyscriptures` icon on unit frames.
**1.3.4**
* **Performance: Spell Lookup Optimization:** Fixed a massive CPU drain and garbage generation issue where the entire spellbook was linearly scanned every frame per unit. Spell IDs are now cached via O(1) dictionary lookup on login and talent/spell changes.
* **Performance: Unit ID Lookup Optimization:** Eliminated heavy C-API calls to `UnitName()` during incoming heals by caching raid and party unit tokens in a fast O(1) hash table that updates on roster changes.
* **Performance: Range Cache GC Leak:** Fixed a continuous memory leak in the range checker caused by string concatenation (`unit .. "_" .. range`) running every frame. Range states are now stored in a nested numeric table cache.
* **Integrations Bug Fix:** Removed stray translation text from `HealBot_Integrations.lua` that caused Lua syntax errors on load.
**1.3.3** **1.3.3**
* **Chat Panel Refactor:** Completely replaced the spell selection dropdowns in the Chat tab with manual text input boxes, allowing users to type exact spell names (with or without ranks) directly, matching the behavior of the key-bindings configuration. Fixed a string matching bug caused by Vanilla WoW's hidden trailing spaces when comparing spell names, ensuring that both rankless (e.g. `Flash Heal`) and ranked inputs trigger correctly. * **Chat Panel Refactor:** Completely replaced the spell selection dropdowns in the Chat tab with manual text input boxes, allowing users to type exact spell names (with or without ranks) directly, matching the behavior of the key-bindings configuration. Fixed a string matching bug caused by Vanilla WoW's hidden trailing spaces when comparing spell names, ensuring that both rankless (e.g. `Flash Heal`) and ranked inputs trigger correctly.