Skip to content

Use owner-only compiled machine state - #52

Merged
SandroMaglione merged 1 commit into
mainfrom
codex/owner-only-compiled-state
Aug 8, 2026
Merged

Use owner-only compiled machine state#52
SandroMaglione merged 1 commit into
mainfrom
codex/owner-only-compiled-state

Conversation

@SandroMaglione

Copy link
Copy Markdown
Member

Summary

  • store compiled process snapshots in a lightweight owner-only mutable reference
  • keep terminal reservation and observer installation atomic at synchronous Effect boundaries
  • revision-check effectful updates across asynchronous boundaries and stress-test first observation racing on-demand completion

Changeset

  • Added or updated for a library or package-metadata change
  • Not required because this PR does not change src/ or package.json

Validation

  • pnpm check
  • Relevant example checks, when examples changed (not applicable)
  • Reviewed the automated type-performance report, when the public TypeScript API or inference changed (pnpm perf:types; public API unchanged)
  • Reviewed the automated runtime-performance report, when runtime behavior changed

Local three-process comparison: burst +11.5%, observed burst +11.2%, child delivery +19.0%, idle heap -15.2%, and parent-child heap -12.8%.

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Type performance

Measured with TypeScript 6.0.3 and skipLibCheck=true.

Scenario Base PR Difference
Effect only 55 55 0 (0.0%)
Import effect-machine 55 55 0 (0.0%)
Machine.defineStates (3 states) 2,965 2,965 0 (0.0%)
Machine.make (3 states, 2 events) 8,715 8,715 0 (0.0%)
machine.handle (3 states, 2 transitions) 23,492 23,492 0 (0.0%)
machine.handle (depth 8) 117,075 117,075 0 (0.0%)
machine.handle (depth 12) 129,713 129,713 0 (0.0%)
machine.handle (depth 16) 145,055 145,055 0 (0.0%)
machine.handle (depth 24) 183,851 183,851 0 (0.0%)
machine.handle (wide depth 16) 214,189 214,189 0 (0.0%)
machine.handle (parallel/history/choice) 132,667 132,667 0 (0.0%)
machine.handle (4 successive calls) 128,674 128,674 0 (0.0%)
machine exact input/output/error/services 110,584 110,584 0 (0.0%)
execution adapter readiness 127,854 127,854 0 (0.0%)

Marginal instantiations are measured against the matching setup without that API call:

Scenario Base PR Difference
Import effect-machine 0 0 0
Machine.defineStates (3 states) 2,910 2,910 0 (0.0%)
Machine.make (3 states, 2 events) 5,742 5,742 0 (0.0%)
machine.handle (3 states, 2 transitions) 14,777 14,777 0 (0.0%)
machine.handle (depth 8) 109,601 109,601 0 (0.0%)
machine.handle (depth 12) 121,039 121,039 0 (0.0%)
machine.handle (depth 16) 135,181 135,181 0 (0.0%)
machine.handle (depth 24) 171,577 171,577 0 (0.0%)
machine.handle (wide depth 16) 202,224 202,224 0 (0.0%)
machine.handle (parallel/history/choice) 114,331 114,331 0 (0.0%)
machine.handle (4 successive calls) 113,703 113,703 0 (0.0%)
machine exact input/output/error/services 100,670 100,670 0 (0.0%)
execution adapter readiness 102,092 102,092 0 (0.0%)
Check times (informational)
Scenario Base PR
Effect only 0.03s 0.03s
Import effect-machine 0.03s 0.03s
Machine.defineStates (3 states) 0.10s 0.10s
Machine.make (3 states, 2 events) 0.16s 0.16s
machine.handle (3 states, 2 transitions) 0.24s 0.24s
machine.handle (depth 8) 0.51s 0.51s
machine.handle (depth 12) 0.55s 0.55s
machine.handle (depth 16) 0.60s 0.59s
machine.handle (depth 24) 0.71s 0.70s
machine.handle (wide depth 16) 0.77s 0.76s
machine.handle (parallel/history/choice) 0.62s 0.60s
machine.handle (4 successive calls) 0.57s 0.59s
machine exact input/output/error/services 0.50s 0.51s
execution adapter readiness 0.57s 0.56s

Type instantiations are the comparison metric. Check time varies with runner load and is informational only.

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Runtime performance

Median of 5 independent benchmark processes on AMD EPYC 9V74 80-Core Processor with Node v24.18.0.

Pull request baseline

Scenario Effect Machine XState 5 XState 6 alpha
Plan counter transitions 129,109 transitions/s 174,616 transitions/s 142,856 transitions/s
Drain burst with terminal fence 109,121 increments/s 500,315 increments/s 133,164 increments/s
Drain burst with a change observer 86,464 increments/s 494,566 increments/s 132,672 increments/s
Lookup and send to one child 104,951 increments/s 493,131 increments/s 130,090 increments/s
Start and stop a machine 30,741 machines/s 227,998 machines/s 91,017 machines/s
Start and stop a parent with one child 9,469 families/s 91,349 families/s 37,994 families/s

Effect runtime reference points

Scenario Effect Machine Effect runtime primitives
Start and stop a raw compiled process 39,544 processes/s
Start and interrupt a suspended fiber 198,491 fibers/s
Start and stop a queue worker 144,488 workers/s
Start and stop an actor shell 133,316 actors/s
Start and stop two actor shells 82,932 families/s
Update an owner-only mutable snapshot 401,123,145 updates/s
Update a synchronized snapshot 1,979,912 updates/s
Create, resolve, and await a terminal latch 2,174,220 latches/s
Memory profile Effect Machine XState 5 XState 6 alpha Effect runtime primitives
Idle machine 8.8 KiB 3.8 KiB 6.1 KiB
Raw generic managed process 13.2 KiB
Raw compiled process 9.6 KiB
Two independent idle machines 17.1 KiB 7.3 KiB 11.8 KiB
Idle parent with one child 22.1 KiB 5.4 KiB 8.8 KiB
Parent with observed child registry 33.6 KiB
Parent with observed invoked child snapshots 22.3 KiB
Suspended Effect fiber 0.7 KiB
Effect queue with waiting fiber 2.8 KiB
Effect mailbox actor shell 3.2 KiB
Two Effect actor shells 6.9 KiB

Effect Machine change from base

Metric Base Base variability PR PR variability Difference
Plan counter transitions 129,571 transitions/s 2.7% MAD 129,109 transitions/s 1.5% MAD -0.4%
Drain burst with terminal fence 97,025 increments/s 0.8% MAD 109,121 increments/s 3.1% MAD +12.5%
Drain burst with a change observer 82,787 increments/s 1.1% MAD 86,464 increments/s 0.8% MAD +4.4%
Lookup and send to one child 95,224 increments/s 0.4% MAD 104,951 increments/s 0.8% MAD +10.2%
Start and stop a machine 27,938 machines/s 0.5% MAD 30,741 machines/s 2.4% MAD +10.0%
Start and stop a parent with one child 9,078 families/s 4.1% MAD 9,469 families/s 2.8% MAD +4.3%
Idle machine heap per unit 10.5 KiB 0.0% MAD 8.8 KiB 0.0% MAD -15.9%
Raw generic managed process heap per unit 13.2 KiB 0.0% MAD 13.2 KiB 0.0% MAD -0.0%
Raw compiled process heap per unit 11.3 KiB 0.0% MAD 9.6 KiB 0.0% MAD -14.6%
Two independent idle machines heap per unit 20.4 KiB 0.0% MAD 17.1 KiB 0.0% MAD -16.2%
Idle parent with one child heap per unit 25.4 KiB 0.0% MAD 22.1 KiB 0.0% MAD -12.9%
Parent with observed child registry heap per unit 36.9 KiB 0.0% MAD 33.6 KiB 0.0% MAD -8.9%
Parent with observed invoked child snapshots heap per unit 25.6 KiB 0.0% MAD 22.3 KiB 0.0% MAD -12.8%

Effect runtime reference change from base

Metric Base Base variability PR PR variability Difference
Start and stop a raw compiled process 37,467 processes/s 0.6% MAD 39,544 processes/s 1.7% MAD +5.5%
Start and interrupt a suspended fiber 195,771 fibers/s 0.4% MAD 198,491 fibers/s 0.8% MAD +1.4%
Start and stop a queue worker 144,071 workers/s 0.1% MAD 144,488 workers/s 1.3% MAD +0.3%
Start and stop an actor shell 132,591 actors/s 0.3% MAD 133,316 actors/s 1.5% MAD +0.5%
Start and stop two actor shells 71,782 families/s 1.5% MAD 82,932 families/s 2.0% MAD +15.5%
Update an owner-only mutable snapshot 401,123,145 updates/s 0.0% MAD 401,123,145 updates/s 0.0% MAD 0.0%
Update a synchronized snapshot 2,008,064 updates/s 0.6% MAD 1,979,912 updates/s 1.0% MAD -1.4%
Create, resolve, and await a terminal latch 2,127,297 latches/s 1.7% MAD 2,174,220 latches/s 1.3% MAD +2.2%
Versions and interpretation
  • Effect Machine: 0.3.0
  • XState 5: 5.32.5
  • XState 6 alpha: 6.0.0-alpha.27
  • Effect runtime primitives: 4.0.0-beta.105

Higher throughput is better; lower heap is better. Variability is the median absolute deviation across independent processes, relative to their median. Runtime measurements on shared GitHub-hosted hardware remain informational, so small differences should be confirmed across multiple workflow runs.

@SandroMaglione
SandroMaglione merged commit d3dc770 into main Aug 8, 2026
9 checks passed
@SandroMaglione
SandroMaglione deleted the codex/owner-only-compiled-state branch August 8, 2026 18:21
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