Skip to content

perf: optimize CaDecon iteration hot paths#107

Merged
daharoni merged 2 commits into
mainfrom
perf/cadecon-hot-path-optimizations
Mar 21, 2026
Merged

perf: optimize CaDecon iteration hot paths#107
daharoni merged 2 commits into
mainfrom
perf/cadecon-hot-path-optimizations

Conversation

@daharoni
Copy link
Copy Markdown
Contributor

@daharoni daharoni commented Mar 21, 2026

Summary

Performance optimizations

  • Batch SolidJS signals (batch() + bulkUpdateTraceResults): 400 reactive graph traversals per iteration → 1, the highest-impact change
  • Shallow snapshot in snapshotIteration: eliminates ~3.2MB of deep-copied typed arrays per iteration (safe because TraceResultEntry objects are replaced, never mutated)
  • Eliminate double copy in trace buildDispatch: transfer job.trace directly instead of allocating a copy (~1.6MB saved per iteration)
  • Pre-allocated typed arrays in dispatchKernelJobs: two-pass approach replaces push(...spread) which risked stack overflow for >65k samples
  • RasterOverview inner loop: hoist cell/rowBase outside inner px loop, inline dataIndex, remove unused import (~3M fewer Math.floor + function calls at 2x DPR)
  • HistogramCard Math.min/max: manual loop prevents RangeError for arrays >65k elements

Draggable grid resizer

  • New ResizableGrid component wrapping the 2x2 plot layout
  • Drag handles at the column divider, row divider, and center intersection
  • Center handle moves both axes; edge handles move one axis
  • Double-click any handle to reset to default (1/3 + 2/3 columns, 50/50 rows)
  • Clamped to 15–85% range; hidden on mobile (stacked layout)

Test plan

  • npm run typecheck passes (only pre-existing errors in unrelated files)
  • npm run build succeeds
  • Manual: load app, import data, run full iteration loop
  • Progress bar updates smoothly
  • Trace inspector shows correct traces
  • Iteration scrubber navigates history correctly (shallow snapshot change)
  • Convergence/trend charts update each iteration
  • Alpha/PVE distributions update (batching change)
  • Raster overview renders correctly (inner loop change)
  • No console errors or RangeErrors
  • Drag grid dividers to resize panels; double-click to reset
  • Center handle moves both axes simultaneously

🤖 Generated with Claude Code

daharoni and others added 2 commits March 21, 2026 08:03
Batch SolidJS signal updates (400 reactive traversals → 1 per iteration),
replace deep copies with shallow snapshots, eliminate double-copied worker
payloads, use pre-allocated typed arrays instead of push(...spread), hoist
invariants out of inner loops, and replace Math.min/max(...) with manual
loops to prevent stack overflows on large arrays.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a ResizableGrid component with drag handles at the column divider,
row divider, and center intersection. Drag to resize; double-click to
reset to default 1/3 + 2/3 column and 50/50 row split.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@daharoni daharoni merged commit 81c312e into main Mar 21, 2026
2 checks passed
@daharoni daharoni deleted the perf/cadecon-hot-path-optimizations branch March 21, 2026 15:25
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.

1 participant