xstate
xstate copied to clipboard
resolveStop is slow for large systems with unpredictable/random ids
XState version
XState version 5
Description
Stopping a system with lots of children with non-sequential/unpredicatable ids is slow.
Consider a following system
- root
- child 0 with id: uuid()
- child 1 with id: uuid()
- child 2 with id: uuid() ....
- child 1000 with id: uuid()
Starting and stopping such a systems takes way more time than a system with predictable ids like 0
, 1
, 2
...
It probably comes down to this line. https://github.com/statelyai/xstate/blob/cbec1a50a67f64402f811e4ec912795762b5adb9/packages/core/src/actions/stopChild.ts#L45
My guess having unpredictable object keys forces V8 to use less efficient internal structures for object representation.
Maybe using a Map
internally can solve an issue. Although, exposing it externally would be a breaking change.
Expected result
If we provide predictable id
in spawnChild, starting and stopping the system is fast.
for (let i = 0; i < 1_000; i++) {
enqueue.spawnChild('child', {
id: String(i),
});
}
https://github.com/user-attachments/assets/9153faa8-d622-4601-a70e-dc12bbb4a1a7
Actual result
If we provide a random id
, starting and stopping the system takes about 1 second on M3 mac without CPU slowdown.
for (let i = 0; i < 1_000; i++) {
enqueue.spawnChild('child', {
id: self.crypto.randomUUID(),
});
}
https://github.com/user-attachments/assets/eb07c9b2-77f6-408f-b93e-031de4f58a36
Reproduction
https://stackblitz.com/edit/vitejs-vite-y3j896?file=src%2FApp.jsx
Additional context
No response