Skip to content

Conversation

@brnrdog
Copy link
Owner

@brnrdog brnrdog commented Jan 21, 2026

Context

This PR unifies the computed observer and subs into a single structure, eliminating object allocations and pointer indirection in hot paths.

Key Changes

  • Merged observer fields into subs for computeds (subs now doubles as the observer)
  • Split tracking contexts: currentComputedSubs for computeds, currentObserver for effects
  • Removed registerComputed / unregisterComputed (no longer needed)
  • Simplified dirty propagation via isComputed(subs) check

main benchmarks

Benchmark Run 1 Run 2 Run 3 Average
Signal Creation (10k) 646.55ms 638.86ms 628.72ms 638.04ms
Computed Creation (10k) 3627.94ms 3602.15ms 3492.33ms 3574.14ms
Deep Computed Chain (100) 17.78ms 39.66ms 40.55ms 32.66ms
Signal Updates (100 observers) 362.33ms 360.68ms 343.76ms 355.59ms
Wide Dependency Tree (100) 183.73ms 187.42ms 192.02ms 187.72ms
Batched Updates (100) 244.58ms 242.29ms 267.36ms 251.41ms
Effects (single trigger) 9.59ms 10.27ms 9.73ms 9.86ms

performance-improvements-2 benchmarks

Benchmark Run 1 Run 2 Run 3 Average
Signal Creation (10k) 41.72ms 47.11ms 41.60ms 43.48ms
Computed Creation (10k) 187.47ms 241.38ms 205.26ms 211.37ms
Deep Computed Chain (100) 1.40ms 1.48ms 1.35ms 1.41ms
Signal Updates (100 observers) 53.40ms 83.91ms 54.86ms 64.06ms
Wide Dependency Tree (100) 155.79ms 123.14ms 125.18ms 134.70ms
Batched Updates (100) 293.08ms 155.44ms 163.65ms 204.06ms
Effects (single trigger) 3.98ms 3.53ms 3.83ms 3.78ms

Benchmarks comparison

Benchmark main perf-improvements-2 Speedup
Signal Creation (10k) 638.04ms 43.48ms 14.7× faster
Computed Creation (10k) 3574.14ms 211.37ms 16.9× faster
Deep Computed Chain (100) 32.66ms 1.41ms 23.2× faster
Signal Updates (100 observers) 355.59ms 64.06ms 5.6× faster
Wide Dependency Tree (100) 187.72ms 134.70ms 1.4× faster
Batched Updates (100) 251.41ms 204.06ms 1.2× faster
Effects (single trigger) 9.86ms 3.78ms 2.6× faster

The biggest wins come from eliminating per-computed allocations and reducing pointer chasing during dependency traversal.

Merge the observer object into the subs structure for computed signals,
eliminating one allocation per computed and removing indirection in the
hot path.

Previously computed signals required three objects: backing signal, subs
(subscriber list), and a separate observer. Now the subs structure serves
double duty - it holds both subscriber list fields AND observer fields
(compute, firstDep/lastDep, flags, level) when used for a computed.
@brnrdog brnrdog force-pushed the perf-improvements-2 branch from 92c38da to 12c52a2 Compare January 21, 2026 21:37
@brnrdog brnrdog merged commit f5d0ad1 into main Jan 21, 2026
2 checks passed
@github-actions
Copy link

🎉 This PR is included in version 1.3.3 🎉

The release is available on:

Your semantic-release bot 📦🚀

@brnrdog brnrdog deleted the perf-improvements-2 branch January 22, 2026 22:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants