Commit 8b7309e
bindings-typescript: share the string codec and add an ASCII fast path to writeString (#5783)
# Description of Changes
`BinaryWriter.writeString` allocates a fresh `TextEncoder` plus a
temporary `Uint8Array` for every string it writes, and
`BinaryReader.readString` a fresh `TextDecoder` for every string it
reads. Both run once per string column per row on every
insert/update/find/scan inside a module, so the per-call allocations
dominate the cost of string columns.
This PR:
- **Writer:** writes pure-ASCII strings straight into the writer buffer,
one byte per char, with no intermediate allocation; non-ASCII input
falls back to a single shared `TextEncoder`. (`TextEncoder.encodeInto`
would be the natural tool, but the module host's `TextEncoder` does not
provide it, so the fast path is a plain loop.)
- **Reader:** one shared `TextDecoder` instead of one per call. The
decode itself is unchanged; a per-char ASCII loop was measured and is
slower than a single `decode` at typical field lengths, so the reader
keeps it.
Output is byte-identical to the previous implementation (tests compare
against `TextEncoder` for empty, ASCII, Latin-1, CJK, astral/surrogate
pairs, mixed, 10k-char strings, and buffer growth from a 1-byte initial
capacity).
Measured inside a module on a stock 2.8.2 server (20k inserts,
`Date.now()` around the loop):
| table | before | after |
|---|---|---|
| 12 string columns | 255-300 ms | 78-88 ms |
| 12 f64 columns (control) | ~42-124 ms | unchanged |
| 1 string column holding a 305-byte JSON blob | ~80 ms | ~60 ms |
The same bytes through fewer allocations; the f64 control shows the rest
of the insert path was never the bottleneck.
# API and ABI breaking changes
None. Same wire bytes, same public surface.
# Expected complexity level and risk
1. Two methods, no behavior change beyond allocation; covered by
byte-equality tests.
# Testing
- [x] `crates/bindings-typescript`: `vitest run` (29 files, 301 tests)
including the new `writeString` suite (encodes like `TextEncoder` for
empty / ASCII / Latin-1 / CJK / astral / mixed / 10k-char inputs, grows
from a 1-byte buffer, round-trips through `readString`, consecutive
writes stay contiguous).
- [x] `eslint` and `prettier --check` on the touched files.
- [x] Exercised end to end by a module publishing to a 2.8.2 server with
string, option<string> and mixed-type rows, including non-ASCII round
trips through the HTTP call path.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
# Rollback safety impact
n/a
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>1 parent d7237e0 commit 8b7309e
3 files changed
Lines changed: 85 additions & 4 deletions
File tree
- crates/bindings-typescript
- src/lib
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
1 | 4 | | |
2 | 5 | | |
3 | 6 | | |
| |||
196 | 199 | | |
197 | 200 | | |
198 | 201 | | |
199 | | - | |
| 202 | + | |
200 | 203 | | |
201 | 204 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
3 | 6 | | |
4 | 7 | | |
5 | 8 | | |
| |||
206 | 209 | | |
207 | 210 | | |
208 | 211 | | |
209 | | - | |
210 | | - | |
211 | | - | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
212 | 233 | | |
213 | 234 | | |
Lines changed: 57 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
186 | 186 | | |
187 | 187 | | |
188 | 188 | | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
0 commit comments