Operator tree optimiser
In order to prevent operators from calculating the same fields multiple times, one can set variables and input these into the operator tree.
The variables are set via a FieldAdapter
. This has been used in !417 (merged).
An operator tree takes as an input a Field and outputs a Field. Cutting out equal subtrees and using their output as the new input for the pruned operator tree is one way to achieve more performance. This is done by optimize_subtrees
.
There are some more improvements one has to make: _OpChain
operators make the tree very complex and they have to be unpacked.
In op2(op1) + op1
the first Summand has to be checked for whether it contains parts of the second Summand.
optimize_node
does this, while optimize_all_nodes
traverses the tree and applies it to (usually, see Problem 1) every node.
Some Problems:
-
Currently only searching for nodes at the end of operator chains, but
optimize_all_nodes( (op + op)(op + op) )
can happen -
Subtrees are only replaced at node points, but one should also compare the vertices above and replace it
-
Only comparing by ids is done, one might add a cache to prevent same operators from going unnoticed (similar to the
DomainTuple
cache -
op = optimize_subtrees(optimize_all_nodes(op))
generates better results thanop = optimize_all_nodes(optimize_subtrees(op))
.
As of now I'm unsure in how far changing the way the operator trees are stored could be improved to make this optimisation easier and/or faster.