Skip to content

script optimization - #1044

Open
HEIHUAa wants to merge 4 commits into
CodenameCrew:mainfrom
HEIHUAa:script-optimization
Open

script optimization#1044
HEIHUAa wants to merge 4 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.

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.

2 participants