Nodes: Improve performance when freeing a node tree

This commit makes freeing a node tree about 25 to 30 times faster.
Freeing a node tree happens whenever it is edited. Freeing a node
tree with about 4000 nodes went from 30-50ms to about 2 ms.

This was so slow before because for every node that was freed
when freeing the node tree, `node_free_node` looped over all
other nodes to detach frames, and then looped over all links to
remove any links connected to the node. That was all pointless
work because everything else is about to be freed anyway.

Instead, move that "detaching" behavior to the dedicated function
for removing a single node, and to the "local" version of the free
function to be safe, since I know less about what that version expects.

Differential Revision: https://developer.blender.org/D13636
This commit is contained in:
Hans Goudey 2021-12-21 09:23:48 -06:00
parent 8cf1994455
commit bdbd0cffda
1 changed files with 10 additions and 5 deletions

View File

@ -281,7 +281,7 @@ static void ntree_free_data(ID *id)
/* Unregister associated RNA types. */
ntreeInterfaceTypeFree(ntree);
BLI_freelistN(&ntree->links); /* do first, then unlink_node goes fast */
BLI_freelistN(&ntree->links);
LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
node_free_node(ntree, node);
@ -3080,10 +3080,6 @@ static void node_free_node(bNodeTree *ntree, bNode *node)
/* can be called for nodes outside a node tree (e.g. clipboard) */
if (ntree) {
/* remove all references to this node */
nodeUnlinkNode(ntree, node);
node_unlink_attached(ntree, node);
BLI_remlink(&ntree->nodes, node);
if (ntree->typeinfo->free_node_cache) {
@ -3135,6 +3131,12 @@ void ntreeFreeLocalNode(bNodeTree *ntree, bNode *node)
{
/* For removing nodes while editing localized node trees. */
BLI_assert((ntree->id.tag & LIB_TAG_LOCALIZED) != 0);
/* These two lines assume the caller might want to free a single node and maintain
* a valid state in the node tree. */
nodeUnlinkNode(ntree, node);
node_unlink_attached(ntree, node);
node_free_node(ntree, node);
}
@ -3179,6 +3181,9 @@ void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool do_id_user)
}
}
nodeUnlinkNode(ntree, node);
node_unlink_attached(ntree, node);
/* Free node itself. */
node_free_node(ntree, node);
}