perf: better effect pruning
#16625We prune effects that have no dependencies and no children. But in many cases we can be more aggressive — if we have an {#if browser}
block, for example, browser
is never going to change and so it's useless to add the block effect to the effect tree, other than to indirectly add its children.
Another example is an attachment that doesn't read anything reactive (i.e. {@attach (node) => {...}}
, which is probably 99% of cases). Today, if you use log_effect_tree
to look at the effect tree immediately after mounting this component...
<input
value='hello'
{@attach (node) => node.select()}
/>
{#if true}
<p>it's true</p>
{/if}
...you see this:
After this PR, it looks like this — notice the intermediate block
effects have been replaced by their children:
This means less memory pressure (effects can be garbage collected), and faster traversal. Though admittedly it's hard to see a clear win in the benchmark results:
sbench_create_signals
time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 261.31ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 279.61ms
gc_time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 56.63ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 63.94ms
sbench_create_0to1
time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 6.99ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 5.60ms
sbench_create_1to1
time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 20.06ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 20.07ms
gc_time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.02ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.04ms
sbench_create_2to1
time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 17.44ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 17.35ms
gc_time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.07ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.93ms
sbench_create_4to1
time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 16.07ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 16.07ms
gc_time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.03ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.96ms
sbench_create_1000to1
time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 14.35ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 14.25ms
gc_time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.99ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.01ms
sbench_create_1to2
time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 9.09ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 9.15ms
sbench_create_1to4
time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 7.75ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 7.66ms
sbench_create_1to8
time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 6.78ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 6.59ms
sbench_create_1to1000
time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 7.35ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 7.40ms
gc_time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 0.21ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 0.21ms
kairo_avoidable_owned
time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 511.49ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 505.36ms
gc_time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 17.24ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 19.71ms
kairo_avoidable_unowned
time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 600.08ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 594.71ms
gc_time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 19.25ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 19.15ms
kairo_broad_owned
time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 489.90ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 489.56ms
gc_time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.86ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.71ms
kairo_broad_unowned
time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 482.70ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 484.67ms
gc_time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.90ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.84ms
kairo_deep_owned
time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 209.22ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 210.22ms
gc_time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.21ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.10ms
kairo_deep_unowned
time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 898.47ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 899.15ms
gc_time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.09ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.09ms
kairo_diamond_owned
time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 421.64ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 423.07ms
gc_time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 9.04ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 9.35ms
kairo_diamond_unowned
time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 490.68ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 499.09ms
gc_time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 9.36ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 9.15ms
kairo_triangle_owned
time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 134.03ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 134.58ms
gc_time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.68ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.61ms
kairo_triangle_unowned
time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 230.25ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 230.06ms
gc_time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.85ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.72ms
kairo_mux_owned
time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 324.89ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 324.79ms
gc_time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.43ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.48ms
kairo_mux_unowned
time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 452.41ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 458.13ms
gc_time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.43ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.42ms
kairo_repeated_owned
time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 76.93ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 76.88ms
gc_time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.38ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.31ms
kairo_repeated_unowned
time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 74.53ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 74.47ms
gc_time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.38ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.33ms
kairo_unstable_owned
time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 116.03ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 116.20ms
gc_time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.21ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.26ms
kairo_unstable_unowned
time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 133.59ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 134.06ms
gc_time: fastest is a (better-effect-pruning)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.24ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.27ms
mol_bench_owned
time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 308.95ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 304.83ms
mol_bench_unowned
time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 324.30ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 322.13ms
gc_time: fastest is b (main)
a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 0.42ms
b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 0.37ms
I suspect this is a case where a benchmark fails to capture the reality of a large application.
feat:
, fix:
, chore:
, or docs:
.packages/svelte/src
, add a changeset (npx changeset
).pnpm test
and lint the project with pnpm lint
Latest commit: 514699a
The changes in this PR will be included in the next version bump.
Name | Type |
---|---|
svelte | Patch |
Not sure what this means? Click here to learn what changesets are.
Click here if you're a maintainer who wants to add another changeset to this PR
pnpm add https://pkg.pr.new/svelte@16625