Closed monoid closed 1 month ago
The original reason was that the AST contains a number of fields such as Name(String)
, and by consuming the AST we can evaluate without reallocating those names. Now we have moved on to a bytecode compiler, I'm less convinced by that reasoning. In the meantime, supporting Clone
doesn't seem unreasonable either. CC @stepancheg for thoughts.
I took a look into this. The evaluator takes the AST by value, since the first thing it does is annotate a lot of the nodes in the AST. It does that by consuming the input AST and producing a new AST tagged with the right data. That means that while the evaluation doesn't really consume the AST, it would be a lot of effort to change it to not consume it.
Fortunately adding a Clone to AstModule isn't hard. I've put up a diff internally for that.
9b6115728cf79bee208c167aef093456f1677714 now adds Clone, so if you want to do multiple evaluations, just clone it.
@ndmitchell thanks! I will try to benchmark it...
Well, the profit on the ./benchmark/benchmark.py
is clear:
parsing AST time: [53.628 µs 53.644 µs 53.660 µs]
Found 7 outliers among 100 measurements (7.00%)
2 (2.00%) high mild
5 (5.00%) high severe
cloning AST time: [4.8612 µs 4.8755 µs 4.8877 µs]
The ./starlark/hello_world.star
demonstrates similar improvement.
Fantastic - can we close this issue then?
Yes, thank you!
Currently
eval_module
consumesAstModule
instance, so one has to parse the script for each invocation, making it impossible to cache the AST. You cannot even clone anAstModule
instance.