Precompute data at top level with grab
#511
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The
grabexpression is used to capture data explicitly in closures. Until now, it could not be used outside closures. For more information aboutgrab, see #316This PR adds a feature which lets you precompute data in sources with
grab. It leads to better performance when using immutable data in inner loops.The motivation behind this feature is to improve performance for procedurally generated content, which often uses a lot of immutable data (e.g. audio), and when the data can not be passed in to the script, e.g. by calling a Dyon function from Rust for each sample (44100 times a second).
For example, here is a program without
grab:It takes 8.28 seconds to run this on my computer.
Here is the same program with
grab:The time is now reduced to 1.84 seconds.
Notice that this only works with pure data. You can not do any computation, e.g.
grab 1 + 3. This is because precomputing happens when the script is loaded, which should not execute any code.The following data can be precomputed:
[false; 24][1, 2, 3]{a: 1, b: 2}(1, 2, 3, 4)link {1 "hi" false}The data structures can be nested, e.g.
[[1, 2], [3, 4]]or[{a: 1, b: 3}, {a: 2, b: 4}].Since the
grabexpression at top level injects the variable into the AST, when you mutate the variable Dyon will use copy-on-write. This means thatgrabexpressions at top level is slower when mutating the variable, but faster when only reading from it.