Skip to content

Commit 27db9eb

Browse files
committed
docs(readme): Lua decode ~18 -> ~91 MB/s after string.buffer FFI rewrite
Update the perf table and optimization notes to reflect the LuaJIT string.buffer work (decode now ~91 MB/s, outpacing encode).
1 parent e425293 commit 27db9eb

1 file changed

Lines changed: 2 additions & 2 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ All implementations share the same byte↔glyph map and pass the same test suite
4848
|---|---|---|
4949
| **Zig** (ReleaseFast) | ~107 MB/s | ~275 MB/s |
5050
| **C** (standalone, `-O3`) | ~61 MB/s | ~141 MB/s |
51-
| **Lua** (LuaJIT) | ~41 MB/s | ~18 MB/s |
51+
| **Lua** (LuaJIT) | ~41 MB/s | ~91 MB/s |
5252
| **Node.js** | ~12 MB/s | ~15 MB/s |
5353

5454
The WebAssembly build is compiled from the same C core. Reproduce on your machine with `IMPLEMENTATION_TO_TEST=<binary> ./test/benchmark_test` (defaults to the Zig build and announces the implementation under test).
@@ -59,7 +59,7 @@ Key optimizations in the Zig core:
5959
- **O(1) decode lookup**: direct tables for 1-, 2-, and 3-byte UTF-8 sequences instead of an O(log 256) binary search.
6060
- **No inner decode loop**: a single UTF-8 length check + direct lookup per character.
6161

62-
The C and Lua decoders were brought in line with this approach in a measured optimization pass: C now uses direct 1-/2-byte lookup tables (**1.9×** decode), and Lua resolves each glyph by its UTF-8 leading-byte length instead of brute-forcing all four lengths (**1.8–3.6×** decode, up from ~8 MB/s). Every optimization is benchmarked before and after, and a continuous memory-leak suite (`test/leak_test`) guards the FFI and C paths against regressions.
62+
The C and Lua decoders were tuned in a measured pass: C uses direct 1-/2-byte lookup tables (**1.9×** decode). Lua got two passes — resolving each glyph by its UTF-8 leading-byte length (instead of brute-forcing all four), then writing decoded bytes straight into a LuaJIT `string.buffer` via its FFI `reserve`/`commit` API (no per-byte `string.char`). Together that took Lua **decode from ~8 to ~91 MB/s** — now faster than its own encode (which uses `string.buffer:put`, ~1.2×). Every optimization is benchmarked before and after (hyperfine), and a continuous memory-leak suite (`test/leak_test`) guards the FFI/C paths against regressions.
6363

6464
The optional PGO path (`make pgo-ffi`) adds a further ~1–3% via profile-guided branch layout, dogfooding the Zig library through its public C ABI.
6565

0 commit comments

Comments
 (0)