Skip to content

script optimization - #1044

Merged
Raltyro merged 5 commits into
CodenameCrew:mainfrom
HEIHUAa:script-optimization
Aug 4, 2026
Merged

script optimization#1044
Raltyro merged 5 commits into
CodenameCrew:mainfrom
HEIHUAa:script-optimization

Conversation

@HEIHUAa

@HEIHUAa HEIHUAa commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Optimized script classes to reduce memory usage, GC pressure, and improve performance.

Script.hx:

  • Added static caching so that the entire Map and most Type.resolveClass calls don't need to be rebuilt every time a script is created. state and window are excluded from this cache because they can change — they remain dynamic and are still reassigned on each creation.
  • Added _EMPTY_ARGS variable for use in places where an empty array is needed. Previously, var result = onCall(func, parameters == null ? [] : parameters); would create a new array when parameters was null, which was unnecessary. This optimization has been moved to Optimization hscript-improved#21, where the same empty array reuse is also applied.

HScript.hx:

  • Added a __parserPool variable to reuse the Parser instance. Since the Parser class is relatively large, reusing it may improve script startup speed and slightly reduce memory usage.
  • Removed if (!interp.variables.exists(funcName)) return null; because interp.variables.get(funcName); combined with the subsequent if (func != null && Reflect.isFunction(func)) effectively already serves as a null check.
  • Fixed an issue where set() could cause incorrect caching in varLocationCache. Added interp.invalidateCache() to clear the cache when necessary.

MultiThreadedScript.hx:

  • Replaced the Array-based contains() O(n) operation with Map's exists() O(1) lookup for the __variables variable.

ScriptPack.hx:

  • Previously, e.call(func, [event]) would create a new array every time — and it did this for every single script. This change significantly reduces unnecessary memory allocations.

GlobalScript.hx:

  • Replaced call("preStateSwitch", []) to eliminate the [] empty array allocation.

These changes have been tested with mods containing a large number of scripts, and no issues were observed.

@SrtHero278

Copy link
Copy Markdown
Collaborator

i personally like how this looks.
image
i may also look into this because this is an interesting discovery if true.

although 2 suggestions:

  • rename _EMPTY_ARGS in PlayState since it's not really empty (maybe _ONE_ARG, you may also be able to use it in other places as well!)
  • see if you can make the parser a static. i've done this multiple times in my work without issues, so it's definitly possible.

@HEIHUAa

HEIHUAa commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

i may also look into this because this is an interesting discovery if true.

Actually, this is certain. However, there's one thing I'm not entirely sure about — for such small collections, is hash-based lookup actually faster than linear search using contains()? Hash reading involves some computation, and the memory might not be very contiguous, so it's hard to guess which one performs better. I think it would be more appropriate to let the test results speak for themselves.

@HEIHUAa

HEIHUAa commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author
  • rename _EMPTY_ARGS in PlayState since it's not really empty (maybe _ONE_ARG, you may also be able to use it in other places as well!)
  • see if you can make the parser a static. i've done this multiple times in my work without issues, so it's definitly possible.

Okay, I'll take a look and see if this change can be made.

@HEIHUAa

HEIHUAa commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Through my testing, I found that Array.contains can be faster than Map.exists when the number of stored items is less than 5 to 7. However, when there are around 20 stored values, Array.contains can be 3 to 6 times slower than Map.exists during lookups.

@Raltyro

Raltyro commented Aug 4, 2026

Copy link
Copy Markdown
Member

Is this good to go?

@HEIHUAa

HEIHUAa commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Is this good to go?

Yes.

@Raltyro

Raltyro commented Aug 4, 2026

Copy link
Copy Markdown
Member

I wonder if it can be optimized further, but for now this is fine

@Raltyro
Raltyro merged commit dbcac9e into CodenameCrew:main Aug 4, 2026
@HEIHUAa
HEIHUAa deleted the script-optimization branch August 4, 2026 12:46
@HEIHUAa

HEIHUAa commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

One more thing — CodenameCrew/hscript-improved#21 may also need to be merged in a relatively synchronized manner. This is because the original parser re‑initialization code didn't fully reset all parameters, which could sometimes cause script errors to be reported even when the script itself was actually fine. I fixed this issue in that pull request.

@HEIHUAa

HEIHUAa commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

I wonder if it can be optimized further, but for now this is fine

Actually, I originally had more changes in mind, but I ended up canceling them due to concerns about potential compatibility issues. In reality, new objects are still being created every frame — and even new classes in some cases. If I had removed those allocations, scripts might end up holding references to classes that no longer exist in the next frame, or values might change unexpectedly. That said, such scenarios seem to be quite rare in practice; most mods don't rely on this behavior and tend to reuse individual parameters instead. If you think this trade‑off is acceptable, I can open a new PR with those changes.

@HEIHUAa

HEIHUAa commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Never mind — I think it would be better to open a new PR tomorrow so you can see exactly what changes are involved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants