perf(tools): keep py-types oneOf rendering linear in schema depth

A deep oneOf chain joined the accumulated union string at every level
(Array.join forces materialization), making it Theta(depth^2) — a
50,000-level chain took ~7.6s. Concatenate with `+` instead: V8 builds a
lazy ConsString that materializes once at the root, matching the array
arm's template-literal laziness and ts-types' composable-document approach.
The whole walk is now linear in depth. Adds a 20,000-level oneOf test
alongside the existing deep-array one; py-types.ts stays at 100% coverage.
This commit is contained in:
Chinesezjc
2026-08-02 17:22:38 +08:00
parent 282b0d7443
commit b0e405a679
2 changed files with 25 additions and 1 deletions
+11 -1
View File
@@ -259,7 +259,17 @@ function renderType(schema: unknown, className: string, state: RenderState): str
continue
}
if (frame.kind === 'oneOf') {
finish(frame.childTypes.join(' | '))
// Concatenate with `+` (not `Array.join`): V8 builds a lazy
// ConsString, so a deep oneOf chain materializes once at the root
// instead of re-materializing the accumulated string at every level
// (which `join` would, making it Θ(depth²)). This matches the array
// arm's template-literal laziness and ts-types' composable-document
// approach — the whole walk stays linear in schema depth.
let union = ''
for (const [index, childType] of frame.childTypes.entries()) {
union = index === 0 ? childType : `${union} | ${childType}`
}
finish(union)
continue
}
/* jscpd:ignore-end */