mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-11-09 20:07:43 +08:00
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:
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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` 仅保存实例自有的关联。
|
||||
|
||||
### 源码地图
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user