Commits
Objects with a `toJSON` method (URL, Temporal, custom types) now serialize
as whatever it returns.
+42B, perf-neutral on realistic shapes.
Symbol and function values now drop instead of throwing or
serializing source, matching JSON.stringify / safe-stable-stringify.
-9B win, perf-neutral.
Some benchmark candidates need an option to turn on cyclic support
Before, every object, array, set, map etc lived in `seen` after it
was finished. That meant each new container paid a `indexOf` scan cost,
across all containers visited so far, which made wide objects scale
poorly.
Now, refs are pushed before walking and popped when done. Active
ancestors are still tracked, so cycle detection stays correct, but
completed refs no logner make sibling checks slower.
Which resulted in a 1.75x perf gain for wide objects, making us now the
fastest across the board. Small, or leaf-heavy objects stayed roughly
the same.
The tradeoff is that repeated, shared, non-cyclic refs are no longer
memoized, so the same large shared object may be walked again. But
common-case objects are unaffected.
Before, every object, array, set, map etc lived in `seen` after it
was finished. That meant each new container paid a `indexOf` scan cost,
across all containers visited so far, which made wide objects scale
poorly.
Now, refs are pushed before walking and popped when done. Active
ancestors are still tracked, so cycle detection stays correct, but
completed refs no logner make sibling checks slower.
Which resulted in a 1.75x perf gain for wide objects, making us now the
fastest across the board. Small, or leaf-heavy objects stayed roughly
the same.
The tradeoff is that repeated, shared, non-cyclic refs are no longer
memoized, so the same large shared object may be walked again. But
common-case objects are unaffected.