How does explicitly setting globals affect optimizations? For example if I set the math global will it de-optimize non-math libraries?
I recently made the switch away from setfenv, so data that a ModuleScript depends on in my game is now automatically initialized at the top instead of lazily via the setfenv environment. This results in reasonably faster data access according to tests, even when caching in the custom environment, although non-lazy data initialization is slower to start up.
It uses globals instead of upvalues if the data is referenced in a nested function in order to reduce memory usage and creation overhead for each created function, because of the +8 bytes per shared upvalue. My compiler automatically assigns globals based on the free constants already used by the script, so I need to know if avoiding certain globals is needed to prevent de-optimization. Ideally, non-mutable upvalues might be optimized like you mentioned, making globals unnecessary for memory-specific use cases.
Here are a few related questions:
Does the new VM add "string" and "find" to the constant table when using string.find, or are they accessed automatically?
Whatās the stance on -0?
For example in the old VM:
print(-0)
print(0)
would result in -0 for both prints.
It might be more intuitive to simply result in "0" when converting -0 to a string, because 0 and -0 have identical behaviors otherwise.
If two of my ModuleScripts utilize the same long string constant, will they share the same memory via the internal string reuse system? or will the string be stored once for each scriptās bytecode?
Yeah, only for this script because globals are sandboxed.
Itās the former - because we remain getfenv-compatible, all optimizations are layered on top of the ānaiveā behavior, and we try to keep the āfallbackā reasonably cheap - e.g. if we didnāt have "string" and "find" around in the custom environment, every call would have to re-create these strings which, even though strings are interned, isnāt that cheap.
Itās a low-priority bug in the new VM (we donāt preserve -0 by accident). This is only relevant for the constant expression ā-0ā, that is all cases where you can get a negative zero dynamically - for example in a floating point underflow scenario - print will still print -0.
They will share memory inside the VM however since scripts are separate, you will still pay the cost of replicating this twice (bytecode), and storing it in memory (if you unparent and reparent the script, we need to reload the bytecode into the VM, so the bytecode stays around). So if the string is really long you should have a separate ModuleScript that contains it.
Oh sorry, I didnāt read your question correctly. If you assign global math in a script, only in that script only accesses to math will become deoptimized - other accesses wonāt be affected.