perf(values): reduce temporary JSON traversal allocations (#7451)

* perf(values): traverse JSON with active container cursors

* fix(values): preserve fractional Proxy index schedules
This commit is contained in:
imccyu
2026-10-28 12:58:29 +08:00
committed by GitHub
6 changed files with 181 additions and 91 deletions
+106 -1
View File
@@ -13,7 +13,7 @@ function objectWithForgedIntrinsicPrototype(revoked = false): Record<string, unk
return Object.assign(Object.create(prototype) as Record<string, unknown>, { value: 1 })
}
describe('snapshotJsonValue', () => {
describe('snapshotJsonValue and isJsonValue', () => {
it('copies the complete JSON scalar vocabulary and rejects unsupported scalars', () => {
const unsupportedFunction = (): void => {}
@@ -120,6 +120,111 @@ describe('snapshotJsonValue', () => {
expect(arrayReads).toBe(1)
})
it.each(['snapshot', 'predicate'] as const)('keeps captured keys and lengths with depth-first getter reads in %s mode', (mode) => {
const reads: string[] = []
const items: unknown[] = [0, 1]
Object.defineProperty(items, 0, {
enumerable: true,
get: () => {
reads.push('item')
items[1] = 7
items.push('added')
return { get child() { reads.push('child'); return 3 } }
},
})
const source = {
get items() {
reads.push('items')
Object.defineProperty(source, 'added', {
enumerable: true,
get: () => { reads.push('added'); return 9 },
})
return items
},
get tail() { reads.push('tail'); return 4 },
}
const result = mode === 'snapshot' ? snapshotJsonValue(source) : isJsonValue(source)
expect(result).toEqual(mode === 'snapshot' ? { items: [{ child: 3 }, 7], tail: 4 } : true)
expect(reads).toEqual(['items', 'item', 'child', 'tail'])
})
it.each(['snapshot', 'predicate'] as const)('rejects an array slot deleted by an earlier getter in %s mode', (mode) => {
const source = [0, 1]
Object.defineProperty(source, 0, {
enumerable: true,
get: () => {
Reflect.deleteProperty(source, 1)
return 0
},
})
expect(mode === 'snapshot' ? snapshotJsonValue(source) : isJsonValue(source))
.toBe(mode === 'snapshot' ? undefined : false)
})
it.each(['snapshot', 'predicate'] as const)('uses one captured Proxy index schedule in %s mode', (mode) => {
for (const secondLength of [2, 1.5, Number.NaN]) {
let coercions = 0
const length = {
valueOf() {
coercions += 1
if (coercions > 2) throw new Error('length was coerced again')
return coercions === 1 ? 2 : secondLength
},
}
const source = new Proxy([1, 2], {
get(target, key): unknown {
if (key === 'length') return length
const value: unknown = Reflect.get(target, key)
return value
},
})
const expected = Number.isNaN(secondLength) ? [] : secondLength === 2 ? [1, 2] : undefined
const result = mode === 'snapshot' ? snapshotJsonValue(source) : isJsonValue(source)
expect(result).toEqual(mode === 'snapshot' ? expected : expected !== undefined)
expect(coercions).toBe(2)
}
})
it.each([false, true])('does not read an array slot outside a fractional Proxy length, throwing slot=%s', (throwing) => {
let reads = 0
const source = new Proxy([42], {
get(target, key): unknown {
if (key === 'length') return 1 - Number.EPSILON / 2
if (key === '0') {
reads += 1
if (throwing) throw new Error('array slot must not be read')
}
const value: unknown = Reflect.get(target, key)
return value
},
})
expect(JSON.stringify(source)).toBe('[]')
expect(snapshotJsonValue(source)).toEqual([])
expect(isJsonValue(source)).toBe(true)
expect(reads).toBe(0)
})
it('detaches every occurrence of a shared child in a wide array', () => {
const shared = { nested: [{ value: 1 }] }
const source = Array.from({ length: 4_096 }, () => shared)
expect(isJsonValue(source)).toBe(true)
const snapshot = snapshotJsonValue(source)!
expect(snapshot).toEqual(source)
shared.nested[0]!.value = 2
snapshot[0]!.nested[0]!.value = 3
expect(source.at(-1)?.nested[0]?.value).toBe(2)
expect(snapshot[0]?.nested[0]?.value).toBe(3)
expect(snapshot.at(-1)?.nested[0]?.value).toBe(1)
})
it('accepts deeply nested valid JSON without using the JavaScript call stack', () => {
let value: JsonValue = 'leaf'
for (let depth = 0; depth < 5_000; depth++) value = [value]
+2 -2
View File
@@ -30,8 +30,8 @@
en: f21b7bd8040a72eb
zh: 19548d3e537c0b5b
/deepseek-ai-dsh-util-values/understand-the-implementation:
en: 36866610a9a7f898
zh: aa2f0e4c3cc12335
en: 191b5a3d906e4957
zh: b9cf264bf8c0674b
/deepseek-ai-dsh-util-values/understand-the-implementation/source-map:
en: 761d4e5f1a53f6a0
zh: 00ae8492171028e4
+1 -1
View File
@@ -61,7 +61,7 @@ Use `assertNever(value, context?)` in the default branch of a closed discriminat
<details>
<summary>Implementation internals — click to expand</summary>
The JSON validator uses an explicit work stack and tracks only the active ancestor chain, so deeply nested values do not consume the JavaScript call stack and repeated non-cyclic references remain valid. Intrinsic arrays and plain objects are recognized across JavaScript realms using native constructor representations from the running engine. Snapshot writes use own data properties, including for names such as `__proto__`. Value operations derive their result only from their arguments; `WeakMapWithValues` stores only instance-owned associations.
The JSON validator keeps one cursor per active container, reads one child at a time, and tracks only the active ancestor chain, so deeply nested values do not consume the JavaScript call stack and repeated non-cyclic references remain valid. Intrinsic arrays and plain objects are recognized across JavaScript realms using native constructor representations from the running engine. Snapshot writes use own data properties, including for names such as `__proto__`. Value operations derive their result only from their arguments; `WeakMapWithValues` stores only instance-owned associations.
### Source map
+1 -1
View File
@@ -61,7 +61,7 @@ const snapshot = snapshotJsonValue(input) as JsonValue
<details>
<summary>实现细节——点击展开</summary>
JSON 校验器使用显式工作栈,并只跟踪当前祖先链,因此深层嵌套值不会消耗 JavaScript 调用栈,重复但无循环的引用仍然有效。内建数组与普通对象通过当前引擎的原生构造器文本表示进行跨 JavaScript realm 识别。快照写入使用自有数据属性,包括 `__proto__` 等名称。值操作的结果只取决于传入参数;`WeakMapWithValues` 仅保存实例自有的关联。
JSON 校验器为每个正在遍历的容器保留一个位置,每次读取一个子项,并只跟踪当前祖先链,因此深层嵌套值不会消耗 JavaScript 调用栈,重复但无循环的引用仍然有效。内建数组与普通对象通过当前引擎的原生构造器文本表示进行跨 JavaScript realm 识别。快照写入使用自有数据属性,包括 `__proto__` 等名称。值操作的结果只取决于传入参数;`WeakMapWithValues` 仅保存实例自有的关联。
### 源码地图
+70 -85
View File
@@ -57,29 +57,23 @@ function enumerableStringKeys(value: object): string[] | undefined {
return keys as string[]
}
type SnapshotDestination =
| { kind: 'root' }
| { kind: 'array'; target: JsonValue[]; index: number }
| { kind: 'object'; target: { [key: string]: JsonValue }; key: string }
type JsonWalkTask =
| { kind: 'visit'; value: unknown; destination?: SnapshotDestination }
| { kind: 'array-item'; source: unknown[]; index: number; target?: JsonValue[] }
| { kind: 'object-property'; source: Record<string, unknown>; key: string; target?: { [key: string]: JsonValue } }
| { kind: 'leave'; source: object }
/** One active container, with child reads in its captured key or index order. */
type JsonWalkFrame =
| { kind: 'array'; source: unknown[]; length: number; index: number; key: number; indices: number[] | undefined; target: JsonValue[] | undefined }
| { kind: 'object'; source: Record<string, unknown>; keys: string[]; index: number; key: string; target: { [key: string]: JsonValue } | undefined }
/** Validate lossless JSON iteratively, optionally materializing a detached snapshot. */
function walkJsonValue(value: unknown, detach: boolean): JsonValue | true | undefined {
const ancestors = new Set<object>()
let root: JsonValue | undefined
const assign = (destination: SnapshotDestination | undefined, item: JsonValue): void => {
if (destination === undefined) return
if (destination.kind === 'root') {
root = item
} else if (destination.kind === 'array') {
destination.target[destination.index] = item
} else {
Object.defineProperty(destination.target, destination.key, {
let parent: JsonWalkFrame | undefined
const assign = (item: JsonValue): void => {
if (parent === undefined) {
if (detach) root = item
} else if (parent.kind === 'array') {
if (parent.target !== undefined) parent.target[parent.key] = item
} else if (parent.target !== undefined) {
Object.defineProperty(parent.target, parent.key, {
value: item,
enumerable: true,
configurable: true,
@@ -88,80 +82,71 @@ function walkJsonValue(value: unknown, detach: boolean): JsonValue | true | unde
}
}
const tasks: JsonWalkTask[] = [{
kind: 'visit',
value,
...(detach ? { destination: { kind: 'root' } as const } : {}),
}]
for (let task = tasks.pop(); task !== undefined; task = tasks.pop()) {
if (task.kind === 'leave') {
ancestors.delete(task.source)
continue
}
if (task.kind === 'array-item') {
if (!Object.prototype.hasOwnProperty.call(task.source, task.index)) return undefined
tasks.push({
kind: 'visit',
value: task.source[task.index],
...(task.target === undefined ? {} : { destination: { kind: 'array', target: task.target, index: task.index } as const }),
})
continue
}
if (task.kind === 'object-property') {
tasks.push({
kind: 'visit',
value: task.source[task.key],
...(task.target === undefined ? {} : { destination: { kind: 'object', target: task.target, key: task.key } as const }),
})
continue
}
const current = task.value
const frames: JsonWalkFrame[] = []
let current: unknown = value
for (;;) {
if (current === null) {
assign(task.destination, null)
continue
}
if (typeof current === 'boolean' || typeof current === 'string') {
assign(task.destination, current)
continue
}
if (typeof current === 'number') {
assign(null)
} else if (typeof current === 'boolean' || typeof current === 'string') {
assign(current)
} else if (typeof current === 'number') {
if (!Number.isFinite(current) || Object.is(current, -0)) return undefined
assign(task.destination, current)
continue
}
if (typeof current !== 'object') return undefined
if (ancestors.has(current)) return undefined
if (Array.isArray(current)) {
if (!hasPlainArrayPrototype(current)) return undefined
const length = current.length
if (Reflect.ownKeys(current).length !== length + 1) return undefined
const target = detach ? [] as JsonValue[] : undefined
if (target !== undefined) assign(task.destination, target)
ancestors.add(current)
tasks.push({ kind: 'leave', source: current })
for (let index = length - 1; index >= 0; index--) {
tasks.push({ kind: 'array-item', source: current, index, ...(target === undefined ? {} : { target }) })
assign(current)
} else {
if (typeof current !== 'object') return undefined
if (ancestors.has(current)) return undefined
if (Array.isArray(current)) {
if (!hasPlainArrayPrototype(current)) return undefined
const length = current.length
if (Reflect.ownKeys(current).length !== length + 1) return undefined
const target = detach ? [] as JsonValue[] : undefined
if (target !== undefined) assign(target)
let indices: number[] | undefined
if (!Number.isInteger(length)) {
// Capture indices with one subtraction for fractional or coercible Proxy lengths.
indices = []
for (let index = length - 1; index >= 0; index--) indices.push(index)
}
frames.push({ kind: 'array', source: current, length: indices?.length ?? length, index: 0, key: 0, indices, target })
} else {
if (!hasPlainObjectPrototype(current)) return undefined
const keys = enumerableStringKeys(current)
if (keys === undefined) return undefined
const target = detach ? {} as { [key: string]: JsonValue } : undefined
if (target !== undefined) assign(target)
frames.push({ kind: 'object', source: current as Record<string, unknown>, keys, index: 0, key: '', target })
}
continue
ancestors.add(current)
}
if (!hasPlainObjectPrototype(current)) return undefined
const keys = enumerableStringKeys(current)
if (keys === undefined) return undefined
const target = detach ? {} as { [key: string]: JsonValue } : undefined
if (target !== undefined) assign(task.destination, target)
ancestors.add(current)
tasks.push({ kind: 'leave', source: current })
for (let index = keys.length - 1; index >= 0; index--) {
const key = keys[index]
/* v8 ignore next -- the loop is bounded by the captured key count. */
if (key === undefined) return undefined
tasks.push({ kind: 'object-property', source: current as Record<string, unknown>, key, ...(target === undefined ? {} : { target }) })
for (;;) {
const frame = frames.at(-1)
if (frame === undefined) return detach ? root : true
const length = frame.kind === 'array' ? frame.length : frame.keys.length
if (frame.index >= length) {
ancestors.delete(frame.source)
frames.pop()
continue
}
const index = frame.index++
parent = frame
if (frame.kind === 'array') {
const key = frame.indices === undefined ? index : frame.indices[frame.indices.length - index - 1]
/* v8 ignore next -- the loop is bounded by the captured index count. */
if (key === undefined) return undefined
if (!Object.prototype.hasOwnProperty.call(frame.source, key)) return undefined
frame.key = key
current = frame.source[key]
} else {
const key = frame.keys[index]
/* v8 ignore next -- the loop is bounded by the captured key count. */
if (key === undefined) return undefined
frame.key = key
current = frame.source[key]
}
break
}
}
return detach ? root : true
}
/**
File diff suppressed because one or more lines are too long