Perf: memoize ImHashStr per seed, inline glyph lookup in ImFont:RenderText

This commit is contained in:
4DBug
2026-10-08 10:21:16 -05:00
parent 623dc5b936
commit cdf72ede17
4 changed files with 70 additions and 9 deletions
+22 -2
View File
@@ -342,9 +342,29 @@ end
--- @param size int?
--- @param seed int?
--- @return int
-- [Luau] memo for whole-string hashes: labels are re-hashed with the same seed every frame.
-- ponytail: whole-memo reset at HASH_MEMO_MAX entries, LRU if ID churn makes it thrash
local hash_memo, hash_memo_n, HASH_MEMO_MAX = {}, 0, 16384
local ImHashStrRaw
function ImHashStr(str, size, seed)
if size == nil then size = #str end
if seed == nil then seed = 0 end
if seed == nil then seed = 0 end
if size == nil or size == #str then
local m = hash_memo[seed]
if m == nil then m = {}; hash_memo[seed] = m end
local h = m[str]
if h == nil then
if hash_memo_n >= HASH_MEMO_MAX then hash_memo = { [seed] = m }; table.clear(m); hash_memo_n = 0 end
h = ImHashStrRaw(str, #str, seed)
m[str] = h
hash_memo_n += 1
end
return h
end
return ImHashStrRaw(str, size, seed)
end
function ImHashStrRaw(str, size, seed)
if str == "" or size == 0 then
return seed -- need to match cpp code edge case behavior while using FNV ourselves
+12 -2
View File
@@ -4641,6 +4641,8 @@ function MT.ImFont:RenderText(draw_list, size, pos, col, clip_rect, text, text_b
local word_wrap_eol
local stop = false
local text_is_str = type(text) == "string"
local lookup, lookup_n, glyphs = baked.IndexLookup.Data, baked.IndexLookup.Size, baked.Glyphs.Data
while s < text_end do
repeat
@@ -4662,7 +4664,8 @@ function MT.ImFont:RenderText(draw_list, size, pos, col, clip_rect, text, text_b
end
end
local c = ImStrByte(text, s)
local c
if text_is_str then c = string.byte(text, s) else c = text[s] end
if c < 0x80 then
s = s + 1
else
@@ -4687,7 +4690,14 @@ function MT.ImFont:RenderText(draw_list, size, pos, col, clip_rect, text, text_b
end
end
local glyph = baked:FindGlyph(c)
local glyph
local gi = (c < lookup_n) and lookup[c + 1] or nil
if gi ~= nil and gi ~= IM_FONTGLYPH_INDEX_NOT_FOUND and gi ~= IM_FONTGLYPH_INDEX_UNUSED then
glyph = glyphs[gi]
else
glyph = baked:FindGlyph(c) -- may load the glyph and grow the tables
lookup, lookup_n, glyphs = baked.IndexLookup.Data, baked.IndexLookup.Size, baked.Glyphs.Data
end
local char_width = glyph.AdvanceX * scale
if glyph.Visible then