sinclairzx81 / typebox

Json Schema Type Builder with Static Type Resolution for TypeScript
Other
4.65k stars 150 forks source link

Revision 0.32.29 #862

Closed sinclairzx81 closed 2 months ago

sinclairzx81 commented 2 months ago

This PR provides an optimization on Intersect Encode and Decode by using a different strategy for resolving key and key schematics. It was noted that Key + Index resolve operations were slow when Index was called per iteration, this PR resolves all schematics in a single call resulting in roughly 2x better performance.

Test Case

import { Type } from '@sinclair/typebox'
import { Value } from '@sinclair/typebox/value'

const N = Type.Transform(Type.Number())
  .Decode(value => value)
  .Encode(value => value)

const I = Type.Intersect([
  Type.Object({ a: N, b: N, c: N }),
  Type.Object({ d: N, e: N, f: N }),
  Type.Object({ g: N, h: N, i: N })
])

const V = Value.Create(I)
const D = Value.Decode(I, V)
const L = 100_000

console.time('intersect-decode')
for(let i = 0; i < L; i++) Value.Decode(I, V)
console.timeEnd('intersect-decode')

console.time('intersect-encode')
for(let i = 0; i < L; i++) Value.Encode(I, D)
console.timeEnd('intersect-encode')

// before:
//
// intersect-decode: 3.541s
// intersect-encode: 3.483s
//
// after:
//
// intersect-decode: 1.509s
// intersect-encode: 1.369s

This PR also updates the Value.Decode and Value.Encode functions to check for HasTransform prior to invoking the codecs. Schematics without Transforms will yield the checked value only leading to significantly better performance. This check was missed on the revision 0.32.0.