From a33dbecb99a102622400c46b461f679c9ad30662 Mon Sep 17 00:00:00 2001 From: Eugene Blikh Date: Fri, 15 May 2026 14:10:03 +0300 Subject: [PATCH] =?UTF-8?q?wire:=20encode=5Fvarint=201-byte=20fast=20path?= =?UTF-8?q?=20(up=20to=203.8=C3=97=20encode=20throughput)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For non-negative Lua numbers under 0x80, return string.char(n) directly — no `to_uint64` cdata allocation, no `out` table, no table.concat. Covers the dominant case for typical payloads: length prefixes for strings <128 bytes, small int field values, enum ordinals, and most tag bytes when codegen-precomputation isn't available. Symmetric to the decode_varint 1-byte fast path in 9f3bfb8 but the payoff is much bigger because the encode path was paying for both a cdata allocation and a list-builder per call, not just a varint loop. Effect (bench/bench.lua, hello.Person): full/10B encode: 13 → 30 MB/s (2.3×) full/100B encode: 125 → 278 MB/s (2.2×) full/1KB encode: 69 → 210 MB/s (3.0×) full/10KB encode: 98 → 352 MB/s (3.6×) full/100KB encode: 108 → 398 MB/s (3.7×) runtime/10B encode: 9 → 16 MB/s (1.8×) runtime/100B encode: 78 → 151 MB/s (1.9×) runtime/1KB encode: 68 → 183 MB/s (2.7×) runtime/10KB encode: 99 → 352 MB/s (3.5×) runtime/100KB encode: 109 → 411 MB/s (3.8×) decode: unchanged alloc/op: unchanged (bench-compare clean) --- runtime/pb/wire.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/runtime/pb/wire.lua b/runtime/pb/wire.lua index 6262045a766e3063d3e08a1b790d7b20326b4fc3..8e21add2974bcf573c114e2a3e54985a02ab8890 100644 --- a/runtime/pb/wire.lua +++ b/runtime/pb/wire.lua @@ -45,7 +45,15 @@ M.to_int64 = to_int64 -- encode_varint(n) -> string -- Accepts uint64_t/int64_t cdata, Lua number, or boolean. +-- +-- Fast path: small non-negative Lua numbers (0..127) become a single +-- string.char(n) call with no cdata allocation, no `out` table, no +-- table.concat. Covers most length prefixes for short strings, many +-- enum ordinals, and most small int values in typical RPC payloads. local function encode_varint(n) + if type(n) == 'number' and n >= 0 and n < 0x80 then + return string.char(n) + end n = to_uint64(n) local out = {} local i = 1