perf: reduce CPU hotspots identified in profiler

- HBD.lua: Cache GetPlayerWorldPosition/GetPlayerZonePosition at 50ms
  intervals instead of hammering GetPlayerMapPosition() every frame.
  Invalidate cache on PLAYER_ENTERING_WORLD and ZONE_CHANGED_* events.
  Expected ~97% reduction in C API position calls (45,570 -> ~1,200 / 10min).

- zoneDB.lua: Replace O(n) linear scan in GetAreaIdByUiMapId with an
  O(1) reverse lookup cache (uiMapIdToAreaIdCache) built at Initialize().
  Cache is kept in sync by ApplyCustomZones and name-match fallback now
  caches its result so subsequent calls are also O(1).

- Tooltip.lua: Throttle GameTooltip OnUpdate hook to 100ms intervals
  (was firing every frame at 60-144 Hz). Added _tooltipLastText cache
  to avoid redundant GetText() + CountTooltip() calls when nothing changed.

- QuestieArrow.lua: Hoist _HasMissingCompletedFlag, _GetCompleteIconType,
  _CollectFinisherSpawns, and _CollectObjective out of _CollectQuestTargets
  to module-level functions. These were re-created as closures on every
  UpdateNearestTargets call (1 Hz). Shared per-cycle context is published
  via _arrow_* module upvalues to avoid closure capture overhead.

- QuestieLearnerComms.lua: Four micro-optimizations:
  (1) Reduce ProcessQueues ticker 0.2s -> 0.5s (still 7x faster than
      minChatInterval of 3.5s).
  (2) Cache hidden channel ID at init; lazy refresh on disconnect.
  (3) Drop LibDeflate compress level 9 -> 1 (fraction of CPU cost).
  (4) O(1) messageCacheCount counter replaces O(n) pairs() size scan.
This commit is contained in:
Xurkon
2026-03-29 16:42:43 -05:00
parent 2d9d83f265
commit 05ea31bc53
5 changed files with 288 additions and 142 deletions
+24 -12
View File
@@ -34,6 +34,12 @@ QuestieTooltips.lookupKeysByQuestId = {
}
local MAX_GROUP_MEMBER_COUNT = 6
-- Throttle: limit the OnUpdate object-tooltip check to 10 times per second.
-- Without this, the callback fires every frame (60144 Hz) and hammers GetText()
-- + CountTooltip() even when the tooltip hasn't changed.
local _tooltipUpdateInterval = 0.10
local _tooltipLastUpdate = 0
local _tooltipLastText = ""
local _InitObjectiveTexts
@@ -491,28 +497,34 @@ function QuestieTooltips:Initialize()
end
end)
-- Fired whenever the cursor hovers something with a tooltip. And then on every frame
-- Fired whenever the cursor hovers something with a tooltip. And then on every frame.
-- Throttled to _tooltipUpdateInterval (100ms) to avoid per-frame C API pressure.
GameTooltip:HookScript("OnUpdate", function(self)
if QuestiePlayer.numberOfGroupMembers > MAX_GROUP_MEMBER_COUNT then
-- When in a raid, we want as little code running as possible
return
end
local now = GetTime()
if now - _tooltipLastUpdate < _tooltipUpdateInterval then return end
_tooltipLastUpdate = now
if (not self.IsForbidden) or (not self:IsForbidden()) then
--Because this is an OnUpdate we need to check that it is actually not a Unit or Item to think its a
-- Only fires for non-unit, non-item, non-spell tooltips (i.e. object/world tooltips)
local uName, unit = self:GetUnit()
local iName, link = self:GetItem()
local sName, spell = self:GetSpell()
if (uName == nil and unit == nil and iName == nil and link == nil and sName == nil and spell == nil) and (
QuestieTooltips.lastGametooltip ~= GameTooltipTextLeft1:GetText() or
(not QuestieTooltips.lastGametooltipCount) or
_QuestieTooltips:CountTooltip() < QuestieTooltips.lastGametooltipCount
or QuestieTooltips.lastGametooltipType ~= "object"
) and (not self.ShownAsMapIcon) then -- We are hovering over a Questie map icon which adds it's own tooltip
_QuestieTooltips:AddObjectDataToTooltip(GameTooltipTextLeft1:GetText())
QuestieTooltips.lastGametooltipCount = _QuestieTooltips:CountTooltip()
if (uName == nil and unit == nil and iName == nil and link == nil and sName == nil and spell == nil) and (not self.ShownAsMapIcon) then
local currentText = GameTooltipTextLeft1:GetText()
if currentText ~= _tooltipLastText
or (not QuestieTooltips.lastGametooltipCount)
or _QuestieTooltips:CountTooltip() < QuestieTooltips.lastGametooltipCount
or QuestieTooltips.lastGametooltipType ~= "object" then
_QuestieTooltips:AddObjectDataToTooltip(currentText)
QuestieTooltips.lastGametooltipCount = _QuestieTooltips:CountTooltip()
_tooltipLastText = currentText
end
QuestieTooltips.lastGametooltip = currentText
end
QuestieTooltips.lastGametooltip = GameTooltipTextLeft1:GetText()
end
end)
end