Skip to content
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

Optimize NodePath update when renaming or deleting nodes in the editor #50319

Merged
merged 1 commit into from
Jul 22, 2021

Conversation

pouleyKetchoupp
Copy link
Contributor

Fixes #50267 (regression from #49812).

Now the process uses a Map to lookup node pointers instead of iterating over all modified node paths in a list and comparing them one by one for each property to check.

The process also avoids checking properties with empty node paths and does an early exit on deleted nodes to avoid checking the node and its descendants.

Also made a minor change in NodePath::rel_path_to() to avoid resizing a Vector many times for long paths (with copy-on-write each time). Now it's down to 2 resize calls in any case.

I haven't made precise measurements of the performance difference, but with several thousands of nodes with node paths to update, it takes only a couple seconds (about the same it takes without the node path check) as opposed to freezing the editor completely (at least for several minutes).

Project used for tests on 3.x (modified MRP from #50267):
Delete.node.test.zip

Now the process uses a Map to lookup node pointers instead of iterating
over all modified node paths in a list and comparing them for each
property to check.

The process also avoids checking properties with empty node paths and
does an early exit on deleted nodes to avoid checking the node and its
descendants.

Also made a minor change in NodePath::rel_path_to() to avoid resizing a
Vector many times for long paths (with copy-on-write each time). Now
it's down to 2 resize calls in any case.
@@ -240,19 +240,26 @@ NodePath NodePath::rel_path_to(const NodePath &p_np) const {
common_parent--;

Vector<StringName> relpath;
relpath.resize(src_dirs.size() + dst_dirs.size() + 1);
Copy link
Member

@akien-mga akien-mga Jul 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to optimize further, you can probably avoid the two resizes by computing the exact size using common_parent. That might be more error prone though so this approach is probably fine as is (it's more readable probably).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, given how common_parent is calculated I'm a bit afraid of edge cases, like common_parent greater than the size of src_dir or dst_dirs (and maybe other ones). So for now it seems like a good compromise to make sure it's no more than two allocations, without changing the logic too much.

@akien-mga akien-mga merged commit 6b1886f into godotengine:master Jul 22, 2021
@akien-mga
Copy link
Member

Thanks!

@pouleyKetchoupp pouleyKetchoupp deleted the optimize-node-path-check branch July 22, 2021 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Editor freeze when removing or renaming a node has very large scene tree
2 participants