perf(l10n): cache literal (no-arg) translations

Add a locale-keyed cache for no-argument translation lookups so repeated
literal keys resolve without redoing the lookup chain. Reset on locale change
and on locale override application.

Ported from phase3-measured-perf (cherry-pick -x 970dd88), adapted to current
main (hoisted the per-locale cache-table creation; excludes the branch's audit
doc and gitignored test).
This commit is contained in:
Xurkon
2026-06-12 22:54:06 -05:00
parent fb22cd5b2d
commit 1b0f145c87
3 changed files with 34 additions and 0 deletions
+6
View File
@@ -9,6 +9,12 @@
- **[Lua 5.0 - Modulo Operator]** Routed the nine arithmetic `%` modulo sites (daily/weekly quest flag tests, Darkmoon Faire cycle math, learner GUID/flag math, race/class flag tests) through the existing `math.mod` shim. Lua 5.0 has no `%` operator outside string formatting, so this was a parse error on Vanilla 1.12 clients; the addon now parses on 5.0 through Retail. - **[Lua 5.0 - Modulo Operator]** Routed the nine arithmetic `%` modulo sites (daily/weekly quest flag tests, Darkmoon Faire cycle math, learner GUID/flag math, race/class flag tests) through the existing `math.mod` shim. Lua 5.0 has no `%` operator outside string formatting, so this was a parse error on Vanilla 1.12 clients; the addon now parses on 5.0 through Retail.
- **[Lua 5.0 - Options Tab Tables]** Fixed `QuestieOptions.tabs.{auto,dbm,icons,nameplate}` being initialized with `{...}` instead of `{}`. On Lua 5.1 this silently captured the addon varargs into the table; on Lua 5.0 it is a parse error. All sibling tabs already used `{}`, and `Initialize` repopulates the table, so there is no behavioral change. - **[Lua 5.0 - Options Tab Tables]** Fixed `QuestieOptions.tabs.{auto,dbm,icons,nameplate}` being initialized with `{...}` instead of `{}`. On Lua 5.1 this silently captured the addon varargs into the table; on Lua 5.0 it is a parse error. All sibling tabs already used `{}`, and `Initialize` repopulates the table, so there is no behavioral change.
### Performance
> Measured optimizations being cherry-picked from `phase3-measured-perf` and in-game tested one at a time on top of 1.6.4.
- **[l10n - Literal Translation Cache]** Added a locale-keyed cache for no-argument translation lookups so repeated literal keys resolve without redoing the lookup chain. The cache is reset on locale change and when locale overrides are applied. (Ported from `phase3-measured-perf` 970dd88.)
## [Unreleased] - Performance Refactor Branches ## [Unreleased] - Performance Refactor Branches
### Performance ### Performance
+23
View File
@@ -12,6 +12,7 @@ l10n.npcNameLookup = {}
l10n.objectNameLookup = {} l10n.objectNameLookup = {}
l10n.objectLookup = {} l10n.objectLookup = {}
l10n.questLookup = {} l10n.questLookup = {}
l10n.translationCache = {}
---@type QuestieDB ---@type QuestieDB
local QuestieDB = QuestieLoader:ImportModule("QuestieDB") local QuestieDB = QuestieLoader:ImportModule("QuestieDB")
@@ -30,6 +31,10 @@ local supportedLocals = {
['koKR'] = true, ['koKR'] = true,
} }
local function ResetTranslationCache()
l10n.translationCache = {}
end
function l10n:InitializeLocaleOverride() function l10n:InitializeLocaleOverride()
local overridingLocale = QUESTIE_LOCALES_OVERRIDE.locale local overridingLocale = QUESTIE_LOCALES_OVERRIDE.locale
supportedLocals[overridingLocale] = true supportedLocals[overridingLocale] = true
@@ -45,6 +50,8 @@ function l10n:InitializeLocaleOverride()
l10n.translations[id][overridingLocale] = false l10n.translations[id][overridingLocale] = false
end end
end end
ResetTranslationCache()
end end
---@param zoneName string ---@param zoneName string
@@ -193,28 +200,42 @@ function _l10n:translate(key, ...)
key = tostring(key) key = tostring(key)
local argCount = select("#", ...) local argCount = select("#", ...)
if argCount == 0 then if argCount == 0 then
local localeCache = l10n.translationCache[locale]
if localeCache and localeCache[key] ~= nil then
return localeCache[key]
end
if not localeCache then
localeCache = {}
l10n.translationCache[locale] = localeCache
end
local translationEntry = l10n.translations[key] local translationEntry = l10n.translations[key]
if not translationEntry then if not translationEntry then
if (Questie.db.profile.debugEnabled) then Questie:Debug(Questie.DEBUG_ELEVATED, "ERROR: Translations for '" .. tostring(key) .. "' are missing completely!") end if (Questie.db.profile.debugEnabled) then Questie:Debug(Questie.DEBUG_ELEVATED, "ERROR: Translations for '" .. tostring(key) .. "' are missing completely!") end
localeCache[key] = key
return key return key
end end
local translationValue = translationEntry[locale] local translationValue = translationEntry[locale]
if (not translationValue) then if (not translationValue) then
if (Questie.db.profile.debugEnabled) then Questie:Debug(Questie.DEBUG_ELEVATED, "ERROR: Translations for '" .. tostring(key) .. "' are missing the entry for language" , locale, "!") end if (Questie.db.profile.debugEnabled) then Questie:Debug(Questie.DEBUG_ELEVATED, "ERROR: Translations for '" .. tostring(key) .. "' are missing the entry for language" , locale, "!") end
localeCache[key] = key
return key return key
end end
if translationValue == true then if translationValue == true then
-- Fallback to enUS which is the key -- Fallback to enUS which is the key
localeCache[key] = key
return key return key
end end
if type(translationValue) ~= "string" then if type(translationValue) ~= "string" then
if (Questie.db.profile.debugEnabled) then Questie:Debug(Questie.DEBUG_ELEVATED, "ERROR: Translation for '" .. tostring(key) .. "' is not a string!") end if (Questie.db.profile.debugEnabled) then Questie:Debug(Questie.DEBUG_ELEVATED, "ERROR: Translation for '" .. tostring(key) .. "' is not a string!") end
localeCache[key] = key
return key return key
end end
localeCache[key] = translationValue
return translationValue return translationValue
end end
@@ -283,6 +304,8 @@ function l10n:SetUILocale(lang)
else else
locale = _l10n:GetFallbackLocale(GetLocale()) locale = _l10n:GetFallbackLocale(GetLocale())
end end
ResetTranslationCache()
end end
function l10n:GetUILocale() function l10n:GetUILocale()
+5
View File
@@ -218,6 +218,11 @@
<li><strong>[Lua 5.0 &mdash; Modulo Operator]</strong> Routed the nine arithmetic <code>%</code> modulo sites (daily/weekly quest flag tests, Darkmoon Faire cycle math, learner GUID/flag math, race/class flag tests) through the existing <code>math.mod</code> shim. Lua 5.0 has no <code>%</code> operator outside string formatting, so this was a parse error on Vanilla 1.12 clients; the addon now parses on 5.0 through Retail.</li> <li><strong>[Lua 5.0 &mdash; Modulo Operator]</strong> Routed the nine arithmetic <code>%</code> modulo sites (daily/weekly quest flag tests, Darkmoon Faire cycle math, learner GUID/flag math, race/class flag tests) through the existing <code>math.mod</code> shim. Lua 5.0 has no <code>%</code> operator outside string formatting, so this was a parse error on Vanilla 1.12 clients; the addon now parses on 5.0 through Retail.</li>
<li><strong>[Lua 5.0 &mdash; Options Tab Tables]</strong> Fixed <code>QuestieOptions.tabs.{auto,dbm,icons,nameplate}</code> being initialized with <code>{...}</code> instead of <code>{}</code>. On Lua 5.1 this silently captured the addon varargs into the table; on Lua 5.0 it is a parse error. All sibling tabs already used <code>{}</code>, and <code>Initialize</code> repopulates the table, so there is no behavioral change.</li> <li><strong>[Lua 5.0 &mdash; Options Tab Tables]</strong> Fixed <code>QuestieOptions.tabs.{auto,dbm,icons,nameplate}</code> being initialized with <code>{...}</code> instead of <code>{}</code>. On Lua 5.1 this silently captured the addon varargs into the table; on Lua 5.0 it is a parse error. All sibling tabs already used <code>{}</code>, and <code>Initialize</code> repopulates the table, so there is no behavioral change.</li>
</ul> </ul>
<h3>Performance</h3>
<p><em>Measured optimizations being cherry-picked from <code>phase3-measured-perf</code> and in-game tested one at a time on top of 1.6.4.</em></p>
<ul>
<li><strong>[l10n &mdash; Literal Translation Cache]</strong> Added a locale-keyed cache for no-argument translation lookups so repeated literal keys resolve without redoing the lookup chain. The cache is reset on locale change and when locale overrides are applied. (Ported from <code>phase3-measured-perf</code> 970dd88.)</li>
</ul>
<h3>Bug Fixes</h3> <h3>Bug Fixes</h3>
<ul> <ul>
<li><strong>[Map &mdash; Suppress Duplicate Native Quest POIs]</strong> Rather than globally disabling the server/Blizzard objective POIs, Questie now keeps them enabled and hides only the individual Blizzard POI buttons for quests that already have a visible Questie POI (per-quest duplicate-POI suppression in <code>QuestieCompat</code>, hooked at init). Blizzard POIs still appear for quests Questie does not cover, but no longer stack on top of Questie's own objective icons.</li> <li><strong>[Map &mdash; Suppress Duplicate Native Quest POIs]</strong> Rather than globally disabling the server/Blizzard objective POIs, Questie now keeps them enabled and hides only the individual Blizzard POI buttons for quests that already have a visible Questie POI (per-quest duplicate-POI suppression in <code>QuestieCompat</code>, hooked at init). Blizzard POIs still appear for quests Questie does not cover, but no longer stack on top of Questie's own objective icons.</li>