Skip to content

Share zero-input process logic - #59

Merged
SandroMaglione merged 1 commit into
mainfrom
codex/reuse-process-logic
Aug 9, 2026
Merged

Share zero-input process logic#59
SandroMaglione merged 1 commit into
mainfrom
codex/reuse-process-logic

Conversation

@SandroMaglione

@SandroMaglione SandroMaglione commented Aug 9, 2026

Copy link
Copy Markdown
Member

Summary

  • Share the immutable execution descriptor used by zero-input starts of the same machine definition.
  • Keep input-bearing and resumed starts instance-specific, while retaining invoked-child sessions in their existing runtime-address-keyed WeakMap.
  • Add regression coverage proving concurrent invoked children and distinct input-bearing starts remain isolated.

This removes one duplicated closure bundle and invoke-session map per ordinary actor without changing the public API, transition semantics, or type inference. Three independent local heap-slope runs measured approximately 7% less retained heap for idle and independent actors and 6% less for parent-with-child actors; lifecycle throughput remained effectively neutral.

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 (unchanged; local budget still passes)
  • Reviewed the automated runtime-performance report, when runtime behavior changed

@github-actions

github-actions Bot commented Aug 9, 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.23s 0.22s
machine.handle (depth 8) 0.52s 0.51s
machine.handle (depth 12) 0.56s 0.56s
machine.handle (depth 16) 0.60s 0.60s
machine.handle (depth 24) 0.69s 0.69s
machine.handle (wide depth 16) 0.77s 0.76s
machine.handle (parallel/history/choice) 0.62s 0.63s
machine.handle (4 successive calls) 0.58s 0.59s
machine exact input/output/error/services 0.51s 0.52s
execution adapter readiness 0.59s 0.58s

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

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Runtime performance

Median of 5 independent benchmark processes on AMD EPYC 7763 64-Core Processor with Node v24.18.0.

Pull request baseline

Scenario Effect Machine XState 5 XState 6 alpha
Plan counter transitions 99,530 transitions/s 134,894 transitions/s 122,945 transitions/s
Drain burst with terminal fence 82,397 increments/s 398,762 increments/s 112,874 increments/s
Drain burst with a change observer 60,483 increments/s 396,179 increments/s 112,626 increments/s
Lookup and send to one child 77,186 increments/s 395,707 increments/s 108,083 increments/s
Start and stop a machine 18,797 machines/s 184,468 machines/s 73,774 machines/s
Start and stop a parent with one child 7,512 families/s 68,507 families/s 26,795 families/s

Effect runtime reference points

Scenario Effect Machine Effect runtime primitives
Start and stop a raw compiled process 30,628 processes/s
Start and interrupt a suspended fiber 161,238 fibers/s
Start and stop a queue worker 112,032 workers/s
Start and stop an actor shell 102,796 actors/s
Start and stop two actor shells 63,780 families/s
Update an owner-only mutable snapshot 317,863,954 updates/s
Update a synchronized snapshot 1,504,929 updates/s
Create, resolve, and await a terminal latch 1,409,692 latches/s
Memory profile Effect Machine XState 5 XState 6 alpha Effect runtime primitives
Idle machine 7.0 KiB 3.8 KiB 6.1 KiB
Raw generic managed process 12.3 KiB
Raw compiled process 7.6 KiB
Two independent idle machines 13.5 KiB 7.3 KiB 11.8 KiB
Idle parent with one child 15.8 KiB 5.5 KiB 8.8 KiB
Parent with observed child registry 19.9 KiB
Parent with observed invoked child snapshots 15.9 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 110,642 transitions/s 1.2% MAD 99,530 transitions/s 0.7% MAD -10.0%
Drain burst with terminal fence 88,826 increments/s 1.7% MAD 82,397 increments/s 1.7% MAD -7.2%
Drain burst with a change observer 66,039 increments/s 2.4% MAD 60,483 increments/s 1.5% MAD -8.4%
Lookup and send to one child 83,985 increments/s 0.9% MAD 77,186 increments/s 0.9% MAD -8.1%
Start and stop a machine 18,875 machines/s 2.4% MAD 18,797 machines/s 1.1% MAD -0.4%
Start and stop a parent with one child 7,894 families/s 0.9% MAD 7,512 families/s 1.5% MAD -4.8%
Idle machine heap per unit 7.5 KiB 0.0% MAD 7.0 KiB 0.0% MAD -7.1%
Raw generic managed process heap per unit 12.3 KiB 0.0% MAD 12.3 KiB 0.0% MAD -0.0%
Raw compiled process heap per unit 7.6 KiB 0.0% MAD 7.6 KiB 0.0% MAD +0.9%
Two independent idle machines heap per unit 14.5 KiB 0.0% MAD 13.5 KiB 0.0% MAD -7.3%
Idle parent with one child heap per unit 16.8 KiB 0.0% MAD 15.8 KiB 0.0% MAD -6.1%
Parent with observed child registry heap per unit 21.0 KiB 0.0% MAD 19.9 KiB 0.0% MAD -4.9%
Parent with observed invoked child snapshots heap per unit 17.0 KiB 0.0% MAD 15.9 KiB 0.0% MAD -6.0%

Effect runtime reference change from base

Metric Base Base variability PR PR variability Difference
Start and stop a raw compiled process 30,487 processes/s 1.2% MAD 30,628 processes/s 0.4% MAD +0.5%
Start and interrupt a suspended fiber 165,262 fibers/s 0.6% MAD 161,238 fibers/s 0.3% MAD -2.4%
Start and stop a queue worker 112,905 workers/s 0.4% MAD 112,032 workers/s 0.0% MAD -0.8%
Start and stop an actor shell 102,480 actors/s 0.7% MAD 102,796 actors/s 0.4% MAD +0.3%
Start and stop two actor shells 57,267 families/s 2.1% MAD 63,780 families/s 2.7% MAD +11.4%
Update an owner-only mutable snapshot 316,856,781 updates/s 0.0% MAD 317,863,954 updates/s 0.0% MAD +0.3%
Update a synchronized snapshot 1,530,454 updates/s 0.9% MAD 1,504,929 updates/s 0.4% MAD -1.7%
Create, resolve, and await a terminal latch 1,424,702 latches/s 0.6% MAD 1,409,692 latches/s 1.6% MAD -1.1%
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 7bc3abf into main Aug 9, 2026
9 checks passed
@SandroMaglione
SandroMaglione deleted the codex/reuse-process-logic branch August 9, 2026 09:53
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