-
-
Notifications
You must be signed in to change notification settings - Fork 23.4k
Change Node set_name
to use StringName, slightly improves performance
#76560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
6c86774
to
5d28466
Compare
5d28466
to
905e400
Compare
905e400
to
695b04f
Compare
695b04f
to
2fb90cb
Compare
Since this breaks ABI compatibility, what can I do to preserve compatibility? |
2fb90cb
to
7b3b337
Compare
This should be addressable via And after that you should remove this line from the expected errors (it won't be needed once you add the compatibility method):
|
7b3b337
to
5ec8236
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And Validate extension JSON: Error: Field 'classes/Node/methods/set_name/arguments/0': type changed value in new API, from "String" to "StringName".
needs to be added to 4.1-stable.expected
instead of the hash error that you removed.
5ec8236
to
50b1830
Compare
50b1830
to
54e9fb9
Compare
This doesn't break compatibility in C# because we don't expose the property accessors, so no additional changes should be needed for C#. With this PR, we likely don't need to special-case this anymore in the C# bindings generator: godot/modules/mono/editor/bindings_generator.cpp Lines 1951 to 1953 in 6afd320
|
f272666
to
5129f1a
Compare
f8117cd
to
5578944
Compare
5578944
to
2dacd28
Compare
2dacd28
to
ed0f992
Compare
79feb41
to
9b711b5
Compare
3e3a3eb
to
2d35330
Compare
2d35330
to
ffca5e8
Compare
ffca5e8
to
8aede51
Compare
38dc65d
to
f727340
Compare
f727340
to
9eda6b3
Compare
9eda6b3
to
8b0c1ae
Compare
8b0c1ae
to
79ca6f4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is very welcome! I had actually considered proposing this myself at some point, since it has very obvious performance improvement potential.
The slight slow down on invalid name calls is expected but acceptable as the cold path.
I think however your change can be made a bit simpler by focusing on the main proposal of changing the parameter, I don't think the change to validate_node_name
is needed :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good code wise. I cannot vouch for the correctness of the compat header, but it looks correct too.
To re-iterate, I agree this is a good change. It's always good to match parameters closely to what is actually needed, and the tests show it's impactful.
I think there is one case where it breaks compatibility to GDScript code, which would be NodePath
arguments:
set_name(^"Test")
However, I think this is acceptable.
79ca6f4
to
4c942d5
Compare
0a02b62
to
8831bdc
Compare
8831bdc
to
a7cc734
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested locally, it works as expected. Code looks good to me.
Testing project: test_node_stringname_performance.zip
Same benchmark as in OP, but with 5 million iterations for each scenario instead of 1 million to reduce variance. (10 million will crash due to the node count being too high, even in master
.)
Benchmark
PC specifications
- CPU: Intel Core i9-13900K
- GPU: NVIDIA GeForce RTX 4090
- RAM: 64 GB (2×32 GB DDR5-5800 C30)
- SSD: Solidigm P44 Pro 2 TB
- OS: Linux (Fedora 41)
Using a release optimized export template (production=yes lto=full
).
master
Time elapsed (valid name): 514795 usecs
Time elapsed (invalid name): 642047 usecs
This PR
Time elapsed (valid name): 458555 usecs
Time elapsed (invalid name): 654856 usecs
Needs rebase |
a7cc734
to
a404b66
Compare
Thanks! |
This fixes `Node::set_name()` to release the old unique name before performing the rename. godotengine#76560 changed the code to update `data.name` before calling `_release_unique_name_in_owner()`, causing to incorrectly try releasing the new name instead of the old name. Fixes godotengine#108683
This fixes `Node::set_name()` to release the old unique name before performing the rename. godotengine#76560 changed the code to update `data.name` before calling `_release_unique_name_in_owner()`, causing to incorrectly try releasing the new name instead of the old name. Fixes godotengine#108683
This fixes `Node::set_name()` to release the old unique name before performing the rename. godotengine#76560 changed the code to update `data.name` before calling `_release_unique_name_in_owner()`, causing to incorrectly try releasing the new name instead of the old name. Fixes godotengine#108683
This PR changes the
Node::set_name()
method to use StringName. This code skips StringName construction in the case where the desired name is already a valid node name. This improves performance by about 15% to 20% in my testing in the case where the desired name is already valid (the common case, the happy code path).The code has been split up into multiple methods.
invalid_node_name_index()
finds the index of the first character that would be invalid for a node name. Then this is passed tovalidate_node_name_internal()
which starts replacing the invalid characters from that index. The same logic used to exist combined into one method, but having it be separate allows us to speed upNode::set_name()
. The logic ininvalid_node_name_index()
is even slightly simpler because it doesn't have to keep track ofbool valid
, it just returns if invalid. However, the existingvalidate_node_name()
is still present as a wrapper, for being exposed to GDScript and is also used in many other parts of the codebase. I also renamed some local variables for readability. I'm open to any suggestions if this can be improved further.Test and benchmarking code:
Results:
Without calling set_name, just accessing the array:
Time elapsed: 28971 (varies between about 25k and 30k)
This PR with valid name, skips StringName construction:
Time elapsed: 132565 (varies between about 120k and 140k)
This PR with invalid name:
Time elapsed: 220087 (varies between about 200k and 230k)
Current master with valid name:
Time elapsed: 160325 (varies between about 150k and 170k)
Current master with invalid name:
Time elapsed: 213259 (varies between about 190k and 220k)
I also did some testing with longer StringNames and the speed improvement gets more significant as length increases.