Benchmarks

Apple M1 Pro, 2026-10-31.

5.9xfaster on Node 22 (short)
3.1-3.2xfaster on Node 24
3.0-3.3xfaster on Bun 1.4.4
1.48 MBdarwin-arm64 binary

thaiwrap vs Intl.Segmenter wrapper

Average time per call, lower is better. "short" is the 38-character example. "long" is the same text repeated 300 times. Bars are scaled to the reference.

Node 22.19.0 short
thaiwrap 3.35 µs
Intl.Segmenter 19.80 µs
5.91x
Node 22.19.0 long
thaiwrap 869 µs
Intl.Segmenter 5,010 µs
5.76x
Node 24.22.2 short
thaiwrap 3.46 µs
Intl.Segmenter 11.00 µs
3.18x
Node 24.22.2 long
thaiwrap 859 µs
Intl.Segmenter 2,630 µs
3.06x
Bun 1.4.4 short
thaiwrap 2.90 µs
Intl.Segmenter 9.70 µs
3.34x
Bun 1.4.4 long
thaiwrap 714 µs
Intl.Segmenter 2,140 µs
3.00x

The reference is the wrapper used in the tests. It breaks at word boundaries, so it does the same work as thaiwrap only on Thai-letter text such as these inputs.

Pure Rust core

BenchmarkInputmaxLengthµs per call
short1x sample (38 chars)101.89
long300x sample10555.62
mixed50x Thai/Latin/emoji20115.90
overflow_max4300x sample4760.21
graphemes_long300x sample, graphemes10632.32

criterion mean, median of 3 runs. Single machine, not guaranteed idle. Numbers from docs/m0/benchmarks.md.

Run it yourself

bun run build
bun run bench          # Bun
node bench/index.mjs   # Node
cargo bench -p thaiwrap-core