Faster way to push strings to Lua stack #1485
Replies: 4 comments
-
Using a table for this sounds like the best choice. So sounds like something that can be a luaL_ (lualib) helper working on the existing infrastructure rather than something new and bespoke. |
Beta Was this translation helpful? Give feedback.
-
Sorry for the delay. Perhaps just using the registry is the easiest way since it can be accessed from any Lua binding already. Would it make GC any faster if those strings in registry are marked as 'fixed'? If so, maybe it would make sense to add a new C API function for fixing objects. C functions in module tables could also benefit from this (we have thousands of C functions exposed to scripts). Although I'm thinking the GC still has to traverse those tables because it cannot know that all entries are fixed, so maybe it's not any faster in practice... |
Beta Was this translation helpful? Give feedback.
-
I think marking objects was discussed earlier and it's a bit error-prone. If we do get a table which is essentially a second registry for strings and maybe C functions with no upvalues, it could have special non-nested mark call to skip iteration. I know my experience is limited to a few projects where GC has to do a lot of other work anyway where marking built-in library and a few thousand strings is a drop in the bucket and not that critical, so that's why I lean towards a solution that is a bit more limited, but easier to implement and API misuse should result in UAF (like in a case where table was promised to be fixed, but had an entry added and that entry would skip marking). API to fix 'terminal' objects alone will probably not be as valuable for the reason you mentioned. For your original use case, it's best to focus on what will achieve the faster push on the stack and not on how much GC will be traversing the items. |
Beta Was this translation helpful? Give feedback.
-
What would be the benefit of using a separate table for strings over the registry, if we assume GC is not a factor? I'm assuming those strings would be stored in the array part of the registry table. I could also do some profiling to see how much a difference a couple thousands strings makes for the GC in our case. We have a very tight performance budget for Luau code so even small wins could be important. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
String atoms is a neat way to quickly check strings on the Lua stack, but there is currently no equivalent mechanism for pushing strings to the stack; pushing a string using the C API always incurs string interning cost. For example, lua_rawgetfield spends ~60% of its time in luaS_new even when the string already exists. A canonical use case for faster strings would be enum values which are represented using strings in idiomatic Lua code. Another use case is creating and accessing table fields.
A simple optimization would be to allow registering fixed strings (similar to lua_setlightuserdataname) and later pushing strings using the tags.
Example:
There would be a fixed sized array for string tags in global_State. The size of the array could be configured from luaconf.h.
What do you think?
p.s. An alternative would be to insert such strings to Lua registry, but I'm hesitant because adding thousands of strings there (all possible enum values) does add up to the GC overhead.
Beta Was this translation helpful? Give feedback.
All reactions