Skip to content

Use an index in the loop over the subtags of a combined tag - #21665

Merged
NullVoxPopuli merged 1 commit into
emberjs:mainfrom
NullVoxPopuli-ai-agent:nvp/compute-indexed-loop
Oct 6, 2026
Merged

NullVoxPopuli merged 1 commit into
emberjs:mainfrom
NullVoxPopuli-ai-agent:nvp/compute-indexed-loop

Conversation

@NullVoxPopuli-ai-agent

@NullVoxPopuli-ai-agent NullVoxPopuli-ai-agent commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

The loop over the subtags of a combined tag uses an index in place of for...of. The change is three lines in validators.ts.

Alone, this change has no effect that the reactivity benchmark can separate from noise: the weighted mean is 1.0x of main. It is a part of #21650, and it merges alone.

case main this PR
kairo: mux 20.23 µs 19.72 µs (1.0x)
batch: 10 writes, 1 output 667 ns 664 ns (1.0x)
rows: 1000 rows, write 1 7.19 µs 7.10 µs (1.0x)
weighted geometric mean 1.0x 1.0x

What changes

  • The loop reads subtag[i] with an index. A for...of loop over an array uses the iterator protocol.
  • The loop keeps Math.max. A > comparison ignores the NaN revision of the volatile tag, and a cache that reads that tag then runs one time only.
All 20 cases
case main this PR
propagate: 1 chains x 1 deep 124 ns 121 ns (1.0x)
propagate: 10 chains x 10 deep 5.51 µs 5.47 µs (1.0x)
propagate: 100 chains x 100 deep 724.68 µs 708.19 µs (1.0x)
propagate: 1 chains x 1000 deep 57.18 µs 57.29 µs (1.0x)
propagate: 1000 chains x 1 deep 103.01 µs 101.40 µs (1.0x)
kairo: avoidable propagation 382 ns 361 ns (0.9x)
kairo: broad propagation 7.35 µs 7.10 µs (1.0x)
kairo: deep propagation 3.09 µs 3.08 µs (1.0x)
kairo: diamond 428 ns 424 ns (1.0x)
kairo: mux 20.23 µs 19.72 µs (1.0x)
kairo: repeated observers 365 ns 323 ns (0.9x)
kairo: triangle 755 ns 689 ns (0.9x)
kairo: unstable 574 ns 570 ns (1.0x)
rows: 1000 rows, write 1 7.19 µs 7.10 µs (1.0x)
rows: 1000 rows, write all 118.18 µs 118.70 µs (1.0x)
batch: 10 writes, 1 output 667 ns 664 ns (1.0x)
avoidable: write the same value 6 ns 6 ns (1.0x)
create: 1000 signals 17.84 µs 17.85 µs (1.0x)
create: 1000 computeds, read each 41.11 µs 37.95 µs (0.9x)
create: 1000 outputs 50.30 µs 49.03 µs (1.0x)
weighted geometric mean 1.0x 1.0x

The benchmark is https://github.com/NullVoxPopuli-ai-agent/ember-reactivity-bench. One measurement is the writes of one frame, then one flush that brings every output up to date. Each case of each build runs in its own process, pinned to one core. The numbers are the median of 6 mirrored rounds on Node 24.20.

The run has main, each of the five branches, and #21650 as columns: table and method.

Tests
  • The full suite passes locally: 9495 pass, 18 skipped, 0 failed.
  • type-check:internals, ESLint and Prettier pass.
  • No new test. The tests of combined tags and of the volatile tag cover the loop.

The parts of #21650

#21650 has all five changes in one branch. It stays open as the reference for the combined numbers. The five branches merge with no conflict, and their merge is the same code as the head of #21650.

PR change reactivity benchmark, mean against main
#21663 Pool the trackers of tracking frames 0.6x
#21664 Reuse the combined tag of a tracking frame. Needs #21663 0.6x, with the pool
#21665 (this PR) Index loop over the subtags of a combined tag 1.0x
#21666 Make the functions of a TrackedValue on their first use 0.9x, create is 0.5x
#21667 Store 0 first in the value field of a TrackedValue 1.0x, removes one deopt
#21650 all five 0.6x

Rendering was measured for the combined change only: pnpm bench shows 2.1% less script time, in this comment on #21650.

🤖 Generated with Claude Code

The `for...of` loop made one iterator for each computation of a
combined tag.

The loop keeps `Math.max`. A `>` comparison ignores the NaN revision of
the volatile tag.

Split out of emberjs#21650.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@NullVoxPopuli
NullVoxPopuli merged commit 67a9fad into emberjs:main Oct 6, 2026
70 checks passed
@NullVoxPopuli
NullVoxPopuli deleted the nvp/compute-indexed-loop branch October 6, 2026 18:06
@github-actions github-actions Bot mentioned this pull request Oct 6, 2026
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