perf(decode): resolve interfaces through cached type flags

The decoder asked every value whether it implements Unmarshaler or encoding.TextUnmarshaler by boxing it into an interface and asserting, which allocated on every scalar field. A per-type flag cache answers first and an interface value is built only where the assertion can succeed; interface destinations are still asked dynamically. A monomorphic hint in front of the cache keeps the hot walk off the sync.Map probe, and it re-points at published cache entries so a miss allocates nothing.

Representative document: 233 to 167 allocations; long document typed decode: 107 674 to 63 772 allocations, about 6.1 to about 3.8 ms.
This commit is contained in:
2026-09-20 22:15:23 +02:00
parent d00cbb983a
commit 9874464213
2 changed files with 118 additions and 12 deletions
+4
View File
@@ -88,6 +88,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
halved from 67 664 to 31 765. Date-time tokens are validated by a byte
scan instead of regular expressions, repeated keys share one string
across array-of-tables elements, and per-statement buffers are reused.
- Typed decoding is 12 percent faster than in 1.1.0 on the representative
document (9792 ns against 11 147 ns) with 24 percent fewer allocations
(167 against 220); interface lookups resolve through a cached per-type
flag set instead of boxing every value into an interface to ask.
### Fixed