Speed up GDScriptLanguage::finish
#94505
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
(The issue here is more or less a duplicate of #85435, but with the number of scripts cranked up, as well as more complex dependencies.)
Despite the optimizations introduced in #85603 to lessen the exponentially slower shutdown time in
GDScriptLanguage::finish
, this exponential slowdown still very much remains an issue when the number of scripts in your project goes into the hundreds, with complex (potentially circular) dependencies, which is not unreasonable to find in larger projects.Here is an MRP to illustrate the problem, with an accompanying Python script to generate the scripts: slow-gdscript-shutdown.zip
On my machine this MRP spends 12 seconds in
GDScriptLanguage::finish
when quitting the editor.This slowdown is seemingly caused by every script having
GDScript::clear
called on it inGDScriptLanguage::finish
, which in turn causes it to go looking for every dependency that it itself mustclear
, thereby callingGDScript::get_all_dependencies
, which itself ends up callingGDScript::get_dependencies
for every single script in the project, which is fairly costly on top of the obvious exponential complexity of this whole thing.As far as I can tell this work (in the context of
GDScriptLanguage::finish
specifically) is entirely redundant. The whole point of themust_clear_dependencies
stuff inGDScript::clear
is, as mentioned above, to callclear
on any of itsmust_clear_dependencies
, but seeing as how everyGDScript
instance currently alive will haveclear
called on it inGDScriptLanguage::finish
anyway, this work seems to be entirely redundant (again, in the context ofGDScriptLanguage::finish
specifically).This PR speeds things up by simply checking in
GDScript::clear
if we're currently inGDScriptLanguage::finish
and skips the transitive/recursiveclear
for its dependencies if that's the case, which brings the time ofGDScriptLanguage::finish
in the MRP down from 12 seconds to 6 milliseconds on my machine.