xstate icon indicating copy to clipboard operation
xstate copied to clipboard

resolveStop is slow for large systems with unpredictable/random ids

Open ivankoleda opened this issue 7 months ago • 0 comments

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

Screenshot 2024-07-18 at 22 10 50

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

Screenshot 2024-07-18 at 21 38 14

Reproduction

https://stackblitz.com/edit/vitejs-vite-y3j896?file=src%2FApp.jsx

Additional context

No response

ivankoleda avatar Jul 18 '24 21:07 ivankoleda