Skip to content

Commit 4959fba

Browse files
committed
feat(zen): deep chain and read optimizations
- Set CLEAN state after CHECK verification (avoid redundant checks) - Early exit in _updateIfNecessary when source changed - Length caching in loops (avoid repeated .length access) - Optimized read() with observer check first - Guard _updateIfNecessary calls with state check Target improvements: - Very Deep Chain (100 layers): >300K ops/sec (was 249K) - Extreme Read (10000x): >80K ops/sec (was 64K) - Reduced overhead in STATE_CHECK propagation All 48 tests pass.
1 parent 051cb20 commit 4959fba

File tree

3 files changed

+38
-10
lines changed

3 files changed

+38
-10
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
'@sylphx/zen': minor
3+
---
4+
5+
Deep chain and read optimizations for extreme performance
6+
7+
OPTIMIZATIONS:
8+
- Set CLEAN state after CHECK verification (avoid redundant checks)
9+
- Early exit in _updateIfNecessary when source changed
10+
- Length caching in loops (avoid repeated .length access)
11+
- Optimized read() with observer check first
12+
- Guard _updateIfNecessary calls with state check
13+
14+
BENCHMARK TARGETS:
15+
- Very Deep Chain (100 layers): Target >300K ops/sec (was 249K)
16+
- Extreme Read (10000x): Target >80K ops/sec (was 64K)
17+
- Deep Chain (10 layers): Maintain 2.2M ops/sec
18+
- Reduced overhead in STATE_CHECK propagation
19+
20+
These optimizations reduce redundant state checks and improve cache locality for deep dependency chains.

packages/zen/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@sylphx/zen",
3-
"version": "3.32.0",
4-
"description": "Zen state management library - extreme minimalism, extreme speed. V3.31: Performance optimizations (fast path for single observers, batch processing, optimized removeSourceObservers).",
3+
"version": "3.33.0",
4+
"description": "Zen state management library - extreme minimalism, extreme speed. V3.33: Deep chain optimizations (early exit, CLEAN state setting, length caching).",
55
"type": "module",
66
"main": "./dist/index.cjs",
77
"module": "./dist/index.js",

packages/zen/src/zen.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,13 @@ class Computation<T> implements SourceType, ObserverType, Owner {
245245
// Track this source in current observer
246246
if (currentObserver) {
247247
track(this);
248-
}
249248

250-
if (this._state & 3) {
249+
// OPTIMIZATION: Only check if necessary
250+
if (this._state & 3) {
251+
this._updateIfNecessary();
252+
}
253+
} else if (this._state & 3) {
254+
// No observer - still need to update if dirty
251255
this._updateIfNecessary();
252256
}
253257

@@ -289,10 +293,11 @@ class Computation<T> implements SourceType, ObserverType, Owner {
289293
// SOLID.JS PATTERN: Check ALL sources recursively first
290294
const sources = this._sources;
291295
if (sources) {
292-
for (let i = 0; i < sources.length; i++) {
296+
const len = sources.length;
297+
for (let i = 0; i < len; i++) {
293298
sources[i]._updateIfNecessary();
294299

295-
// After checking source, see if it changed
300+
// OPTIMIZATION: Early exit if changed (avoid checking remaining sources)
296301
if (sources[i]._time > this._time) {
297302
this._state = (this._state & ~3) | STATE_DIRTY;
298303
break;
@@ -304,9 +309,10 @@ class Computation<T> implements SourceType, ObserverType, Owner {
304309
// Only update if still dirty after checking sources
305310
if ((this._state & 3) === STATE_DIRTY) {
306311
this.update();
312+
} else if ((this._state & 3) === STATE_CHECK) {
313+
// OPTIMIZATION: Set CLEAN if still CHECK after verifying all sources
314+
this._state = (this._state & ~3) | STATE_CLEAN;
307315
}
308-
309-
// Don't set CLEAN here - update() will do it
310316
}
311317

312318
/**
@@ -353,15 +359,17 @@ class Computation<T> implements SourceType, ObserverType, Owner {
353359
// Update sources array
354360
if (this._sources && newSourcesIndex > 0) {
355361
this._sources.length = newSourcesIndex + newSources.length;
356-
for (let i = 0; i < newSources.length; i++) {
362+
const newLen = newSources.length;
363+
for (let i = 0; i < newLen; i++) {
357364
this._sources[newSourcesIndex + i] = newSources[i];
358365
}
359366
} else {
360367
this._sources = newSources;
361368
}
362369

363370
// Add this observer to new sources
364-
for (let i = newSourcesIndex; i < this._sources.length; i++) {
371+
const sourcesLen = this._sources.length;
372+
for (let i = newSourcesIndex; i < sourcesLen; i++) {
365373
const source = this._sources[i];
366374
if (!source._observers) {
367375
source._observers = [this];

0 commit comments

Comments
 (0)