From 2ffc6ebd58b1eb374c43e75566a3fecb1cbf20ef Mon Sep 17 00:00:00 2001 From: Eugene Blikh Date: Sat, 16 May 2026 18:57:15 +0300 Subject: [PATCH] wkt: split length-prefix emission to drop per-field concat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply the split-emit pattern from ac9b9c1 (inline.go + codec.lua) to the WKT hand-rolled encoders. Replace `wire.encode_len(body)` — which allocates `varint(#body) .. body` — with three out slots (tag, varint length, body) wherever the result feeds a `table.concat(out)` accumulator. For StringValue/BytesValue (whose encoders return a single string and can't be split), inline encode_len's chain so LuaJIT folds tag + varint + body into one multi-concat instead of two sequential concats. Same final wire bytes. Touched sites: struct_encode (split the outer entry wrap, inline the inner key/value chain), list_encode, any_encode (type_url, value), fieldmask_encode, and the WRAPPERS LEN-typed encoders. The struct_encode inner entry stays a single chain rather than fanning out into more `out` slots — eight slots per Struct entry regressed B/op and gave no encode win on the wkt-event shape; three slots match the codec.lua nested-message pattern and land the speedup. bench/shapes (wkt-event encode, median across 4 runs): full: 125895 -> 129000 msgs/s (+2.5%) runtime: 115231 -> 120000 msgs/s (+4%) make test 509/509, make jit-trace 23/23, docker conformance binary 1478/0 (unexpected), text suite clean. --- runtime/pb/wkt.lua | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/runtime/pb/wkt.lua b/runtime/pb/wkt.lua index c68f6678db9ef01ca0fc975bafccc39d7068da38..62d00132417ff3a81e87daa1d4cff824e6be6892 100644 --- a/runtime/pb/wkt.lua +++ b/runtime/pb/wkt.lua @@ -202,9 +202,19 @@ for _, spec in ipairs(WRAPPERS) do local decode = wire[dec_fn] local tag = TAG_BY_WIRE[wt] - M[name .. '_encode'] = function(v) - if v == nil or is_default(v) then return '' end - return tag .. encode(v) + if wt == wire.WIRE_LEN then + -- StringValue / BytesValue: skip encode_len's `varint(#v) .. v` and + -- let LuaJIT fold tag + varint + body into a single multi-concat + -- instead of two sequential concats. + M[name .. '_encode'] = function(v) + if v == nil or is_default(v) then return '' end + return tag .. wire.encode_varint(#v) .. v + end + else + M[name .. '_encode'] = function(v) + if v == nil or is_default(v) then return '' end + return tag .. encode(v) + end end M[name .. '_decode'] = function(buf) @@ -321,12 +331,18 @@ struct_encode = function(t) -- Each Struct entry: tag(1, LEN)=0x0a, entry_len, entry_payload -- Entry payload: tag(1, LEN)=0x0a + key_len_prefixed_bytes -- + tag(2, LEN)=0x12 + value_len_prefixed_bytes + -- Split the outer entry wrap so the final `table.concat` joins entries + -- in one pass (matches the codec.lua nested-message pattern). The inner + -- entry stays a single multi-concat: it's cheaper than three more out + -- slots once the entry is small. for k, v in pairs(t) do local key_str = type(k) == 'string' and k or tostring(k) - local entry = '\x0a' .. wire.encode_len(key_str) - .. '\x12' .. wire.encode_len(value_encode(v)) + local val_body = value_encode(v) + local entry = '\x0a' .. wire.encode_varint(#key_str) .. key_str + .. '\x12' .. wire.encode_varint(#val_body) .. val_body n = n + 1; out[n] = '\x0a' - n = n + 1; out[n] = wire.encode_len(entry) + n = n + 1; out[n] = wire.encode_varint(#entry) + n = n + 1; out[n] = entry end return table.concat(out) end @@ -335,8 +351,10 @@ list_encode = function(t) if t == nil then return '' end local out, n = {}, 0 for i = 1, #t do + local body = value_encode(t[i]) n = n + 1; out[n] = '\x0a' - n = n + 1; out[n] = wire.encode_len(value_encode(t[i])) + n = n + 1; out[n] = wire.encode_varint(#body) + n = n + 1; out[n] = body end return table.concat(out) end @@ -464,12 +482,14 @@ any_encode = function(v) local type_url = v.type_url if type_url ~= nil and type_url ~= '' then n = n + 1; out[n] = '\x0a' -- field 1, LEN - n = n + 1; out[n] = wire.encode_len(type_url) + n = n + 1; out[n] = wire.encode_varint(#type_url) + n = n + 1; out[n] = type_url end local value = v.value if value ~= nil and value ~= '' then n = n + 1; out[n] = '\x12' -- field 2, LEN - n = n + 1; out[n] = wire.encode_len(value) + n = n + 1; out[n] = wire.encode_varint(#value) + n = n + 1; out[n] = value end return table.concat(out) end @@ -554,8 +574,10 @@ local function fieldmask_encode(v) if v == nil or #v == 0 then return '' end local out, n = {}, 0 for i = 1, #v do + local s = v[i] n = n + 1; out[n] = '\x0a' -- field 1, LEN - n = n + 1; out[n] = wire.encode_len(v[i]) + n = n + 1; out[n] = wire.encode_varint(#s) + n = n + 1; out[n] = s end return table.concat(out) end