Currently node trees are stored as a linked list of nodes and a linked list of links. That leads to some really inefficient code if you want to walk over that tree. Take a look at this nodeChainIter
function for example. It takes O(n^2)
time and O(k)
stack memory where n
is the amount of nodes and k
is the length of the chain (potentially equal to n
). While the memory needs can be reduced by using an iterative instead of recursive function, the running time complexity remains quadratic if you don’t use any auxiliary data structure.
Being able to quickly find linked nodes is essential for more sophisticated tree walking algorithms. I see two ways to achieve this:
- Every time an operator needs this data structure it builds it based on the current
bNodeTree
struct. This is essentially what is done in Animation Nodes. Every time the node tree changes, this structure is rebuild from scratch because working on the original node tree data is so slow (note: the Python API does not really make it apparent that thesocket.links
orsocket.node
are very inefficient. That hit me hart some years ago.) - Refactor the
bNodeTree
struct to use a different data structure, that supports the operations we need out of the box. Also it would be good to get rid of these linked lists in many places but that is a bigger topic I guess… This should be the preferred solution in my opinion but I don’t know if this is an acceptable change in the Blender source code.
I think we have to go one of these ways sooner or later. The question is which one?
When that is decided, I should be able to do the refactoring myself.