Skip to content

fix: incremental batches#18035

Draft
Rich-Harris wants to merge 118 commits intomainfrom
incremental-batches
Draft

fix: incremental batches#18035
Rich-Harris wants to merge 118 commits intomainfrom
incremental-batches

Conversation

@Rich-Harris
Copy link
Copy Markdown
Member

This overhauls how batches work. The idea is that instead of reactions having both a write version and a DIRTY (or MAYBE_DIRTY) flag, dirtiness is determined solely by comparing the write versions of a reaction's dependencies with the check version of the reaction itself.

When processing a batch, we 'overlay' the latest values with batch_values, batch_cvs and batch_wvs (which could probably be better-named). This means that we can track whether or not a derived/effect is dirty within the batch, rather than potentially re-running it unnecessarily as a batch is reprocessed following a promise resolution.

If I'm honest, this hasn't really worked out the way I hoped. It makes the logic quite a bit simpler in some cases, but there's actually more code now (though it could probably be massaged down). But worse, it has a very detrimental effect on performance:

results of `pnpm bench:compare`
sbench_create_signals
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 24.57ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 24.10ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 4.40ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 4.41ms
sbench_create_0to1
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 124.39ms
    b: ◼                    5.97ms
sbench_create_1to1
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 129.08ms
    b: ◼◼◼                  20.12ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 56.46ms
    b: ◼                    2.16ms
sbench_create_2to1
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 84.98ms
    b: ◼◼◼◼                 17.50ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 29.00ms
    b: ◼                    2.10ms
sbench_create_4to1
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 32.70ms
    b: ◼◼◼◼◼◼◼◼◼            15.36ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 13.85ms
    b: ◼◼◼                  2.03ms
sbench_create_1000to1
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 24.58ms
    b: ◼◼◼◼◼◼◼◼◼◼◼          13.89ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 12.17ms
    b: ◼◼◼                  2.02ms
sbench_create_1to2
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 112.20ms
    b: ◼◼                   8.95ms
sbench_create_1to4
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 103.58ms
    b: ◼                    7.47ms
sbench_create_1to8
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 109.34ms
    b: ◼                    6.66ms
sbench_create_1to1000
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 111.41ms
    b: ◼                    7.51ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 48.00ms
    b:                      0.27ms
kairo_avoidable_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1895.72ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼        1231.32ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 32.51ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼       22.76ms
kairo_avoidable_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1899.67ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼        1210.76ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 34.27ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼        22.97ms
kairo_broad_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1838.15ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼         1113.05ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 8.05ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼       5.75ms
kairo_broad_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1815.56ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼         1116.09ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 7.89ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼       5.44ms
kairo_deep_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1482.06ms
    b: ◼◼◼◼◼◼◼              498.18ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 4.72ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼      3.44ms
kairo_deep_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1475.28ms
    b: ◼◼◼◼◼◼◼              496.21ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 5.28ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼        3.44ms
kairo_diamond_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1651.62ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼         1012.34ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 19.80ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼       14.35ms
kairo_diamond_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1638.43ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼         1002.39ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 20.13ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼      14.66ms
kairo_mux_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1716.83ms
    b: ◼◼◼◼◼                405.11ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.68ms
    b: ◼◼◼◼◼◼◼◼◼◼◼          1.47ms
kairo_mux_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1710.12ms
    b: ◼◼◼◼◼                393.96ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.68ms
    b: ◼◼◼◼◼◼◼◼◼◼           1.27ms
kairo_repeated_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 215.94ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼       152.27ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.52ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼     2.00ms
kairo_repeated_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 219.09ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼       151.63ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.76ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼       1.93ms
kairo_triangle_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 629.44ms
    b: ◼◼◼◼◼◼◼◼◼◼           304.64ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 4.63ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼         2.83ms
kairo_triangle_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 630.28ms
    b: ◼◼◼◼◼◼◼◼◼◼           300.77ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 4.76ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼         2.80ms
kairo_unstable_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 299.84ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼        190.36ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.78ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼      2.04ms
kairo_unstable_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 297.23ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼         184.86ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.81ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼       1.98ms
mol_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 35.78ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  33.27ms
mol_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 35.38ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  32.90ms
repeated_deps_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 284.66ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼      219.12ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.83ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   3.37ms
repeated_deps_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 280.23ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼      216.84ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.98ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  3.78ms

It's possible that this could be alleviated with a few small tweaks (e.g. writing the overlay directly to the signals, and reverting at the end of batch processing) but as of yet I don't know.

It does help a lot with #17908, which isn't nothing. (In fact that was the original motivation for this work — the fact that we over-execute each block effects is a bad bug, and I wasn't able to fix it any other way; maybe I just need to take another run at it.)

Before submitting the PR, please make sure you do the following

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • Prefix your PR title with feat:, fix:, chore:, or docs:.
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.
  • If this PR changes code within packages/svelte/src, add a changeset (npx changeset).

Tests and linting

  • Run the tests with pnpm test and lint the project with pnpm lint

@Rich-Harris
Copy link
Copy Markdown
Member Author

Updated benchmarks — now much more of a toss-up (though kairo_mux_* is still a weak spot):

pnpm bench:compare
a: incremental-batches
b: main

sbench_create_signals
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 33.56ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼    29.13ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 6.65ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 6.65ms

sbench_create_0to1
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   6.03ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 6.66ms

sbench_create_1to1
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼    20.55ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 24.19ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   2.43ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.67ms

sbench_create_2to1
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 17.04ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 17.45ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  2.27ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.33ms

sbench_create_4to1
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 15.69ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 15.86ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.28ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  2.21ms

sbench_create_1000to1
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 14.30ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 14.42ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  2.14ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.31ms

sbench_create_1to2
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 9.22ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 9.38ms

sbench_create_1to4
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 7.58ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 7.77ms

sbench_create_1to8
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  6.29ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 6.48ms

sbench_create_1to1000
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  7.03ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 7.39ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 0.20ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 0.19ms

kairo_avoidable_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1408.06ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  1303.35ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 24.93ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  24.09ms

kairo_avoidable_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1388.97ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   1281.92ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 24.96ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  24.02ms

kairo_broad_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1270.41ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  1193.55ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼     4.38ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 5.54ms

kairo_broad_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1288.69ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   1191.09ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼    4.54ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 5.43ms

kairo_deep_owned
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼    450.97ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 539.15ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼        2.03ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.21ms

kairo_deep_unowned
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼    444.27ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 532.84ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼        2.08ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.18ms

kairo_diamond_owned
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  1042.50ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1092.75ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  13.27ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 14.05ms

kairo_diamond_unowned
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  1037.51ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1077.41ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  13.55ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 14.09ms

kairo_mux_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 636.94ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼        415.54ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.43ms
    b: ◼◼◼◼◼◼◼◼◼◼◼          1.30ms

kairo_mux_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 624.72ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼        398.06ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.42ms
    b: ◼◼◼◼◼◼◼◼◼◼           1.25ms

kairo_repeated_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 160.43ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 160.42ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  1.92ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.04ms

kairo_repeated_unowned
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 159.15ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 161.72ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  2.00ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.06ms

kairo_triangle_owned
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   293.20ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 325.89ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼    2.58ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.02ms

kairo_triangle_unowned
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   291.42ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 323.00ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼    2.50ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.95ms

kairo_unstable_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 216.07ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  202.86ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.01ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.01ms

kairo_unstable_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 211.91ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   195.81ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  1.94ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.01ms

mol_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 34.17ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  33.30ms

mol_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 34.03ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 33.53ms

repeated_deps_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 237.83ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  227.76ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼      2.99ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 4.00ms

repeated_deps_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 233.75ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  224.59ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼     3.09ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.97ms

It's possible the benchmarks aren't covering everything — I would expect there to be some overhead with effects at present, since there's no early-return from is_dirty for effects that are known to be clean. Will continue poking.

(Also, just noticed that tests fail in non-async mode. Gah!)

Rich-Harris added a commit that referenced this pull request Apr 3, 2026
extracted from #18035 — this should have been part of #18047 but I
missed it off, oops. Will self-merge so it doesn't get in the way of
#18035, and because the `performance-investigation` skill is predicated
on this code existing

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
return () => {
flushSync();
assert.deepEqual(log, [20]);
assert.deepEqual(log, [20, 20]);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the one observable-in-the-test-suite behaviour change (though there are things that work now that didn't work before; I should add tests). At first I thought it indicated a bug, but the more I think about it the more I think the previous behaviour is buggy — the effect should run again.

Rich-Harris added a commit that referenced this pull request Apr 3, 2026
This makes the benchmarks slightly more honest — it adds the async flag,
and a benchmark that tests the (common) scenario where most effects are
clean. Relevant to #18035, will self-merge so we can do a fresh
comparison
@Rich-Harris
Copy link
Copy Markdown
Member Author

Okay, tests are all passing, but I update the benchmarks so that they didn't gloss over certain changes in this branch and they show some significant regressions:

Details
a: incremental-batches
b: main

sbench_create_signals
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼      25.51ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 35.07ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼          4.64ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 8.69ms

sbench_create_0to1
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼       5.50ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 7.84ms

sbench_create_1to1
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   20.07ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 22.40ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.19ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.23ms

sbench_create_2to1
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  17.04ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 18.22ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼    2.10ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.46ms

sbench_create_4to1
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  15.39ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 16.18ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.23ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.18ms

sbench_create_1000to1
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  13.94ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 14.59ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  2.12ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.23ms

sbench_create_1to2
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  8.83ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 9.09ms

sbench_create_1to4
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  8.33ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 8.60ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   0.80ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 0.88ms

sbench_create_1to8
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  6.48ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 6.78ms

sbench_create_1to1000
  time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 7.04ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 7.15ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 0.22ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼    0.19ms

clean_effects_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 250.46ms
    b: ◼◼◼◼◼◼◼◼◼            107.34ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  0.50ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 0.52ms

clean_effects_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 248.16ms
    b: ◼◼◼◼◼◼◼◼◼            107.17ms
  gc_time: fastest is a (incremental-batches)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  0.47ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 0.49ms

kairo_avoidable_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1839.20ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼        1171.46ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 27.61ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼    24.04ms

kairo_avoidable_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1806.53ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼        1147.21ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 27.63ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼    23.85ms

kairo_broad_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2381.93ms
    b: ◼◼◼◼◼                636.59ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 9.95ms
    b: ◼◼◼◼◼◼◼              3.67ms

kairo_broad_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2397.44ms
    b: ◼◼◼◼◼                634.75ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 9.81ms
    b: ◼◼◼◼◼◼◼              3.68ms

kairo_deep_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 964.24ms
    b: ◼◼◼◼◼◼               265.92ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 4.81ms
    b: ◼◼◼◼◼                1.24ms

kairo_deep_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 959.99ms
    b: ◼◼◼◼◼                262.41ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 4.86ms
    b: ◼◼◼◼◼                1.19ms

kairo_diamond_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1711.79ms
    b: ◼◼◼◼◼◼◼◼◼            778.79ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 17.64ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼       12.60ms

kairo_diamond_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1691.68ms
    b: ◼◼◼◼◼◼◼◼◼            772.30ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 17.44ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼      12.96ms

kairo_mux_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1021.30ms
    b: ◼◼◼◼◼◼◼◼             391.02ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.47ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼         1.52ms

kairo_mux_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 998.38ms
    b: ◼◼◼◼◼◼◼◼             381.84ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.19ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼       1.48ms

kairo_repeated_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 212.57ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼      158.76ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.25ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   2.05ms

kairo_repeated_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 208.17ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼       143.12ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.24ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   1.99ms

kairo_triangle_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 592.55ms
    b: ◼◼◼◼◼◼◼              211.44ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 4.02ms
    b: ◼◼◼◼◼◼◼◼◼◼◼          2.20ms

kairo_triangle_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 587.28ms
    b: ◼◼◼◼◼◼◼              207.35ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.93ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼         2.27ms

kairo_unstable_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 311.35ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼         184.73ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.57ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼      1.92ms

kairo_unstable_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 306.90ms
    b: ◼◼◼◼◼◼◼◼◼◼◼          175.99ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.62ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼      1.96ms

mol_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 37.59ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   33.10ms

mol_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 36.15ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   32.65ms

repeated_deps_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 343.59ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼        216.25ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.82ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼     3.11ms

repeated_deps_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 338.72ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼        212.22ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.53ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   3.22ms

So the work isn't done yet. Still hopeful we can land this though, it feels pretty nice to me code-wise

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants