~bigbes/tarantool

tarantool-protobuf

ref: fe857ac03631666de689cd0973ce68459505f745 tarantool-protobuf/bench/PERF_LOG.md -rw-r--r-- 18.7 KiB
be42fabb — Eugene Blikh 3 months ago
bench: record u39 (table.new pre-sized result) post-mortem

Attempted emitting table_new(0, N) for decode result tables. Tests
passed, JIT passed, but small-payload decode (10B, 100B) regressed
15-18% because the table.new upvalue-call cost exceeds any rehash
savings at that scale, and the small case never reaches the first
rehash anyway. Large-payload decode flat. Confirms drm's claim that
alloc shape is not the bottleneck on the bench corpus.

Code change reverted; only the writeup lands.

beads-tarantool-protobuf-u39
a6eebdb3 — Eugene Blikh 3 months ago
codegen: local counter per repeated field on decode

Replaces `list[#list + 1] = val` with `_n_<fname> = _n_<fname> + 1;
list[_n_<fname>] = val` in every generated M.X_decode repeated-field
append site. One counter local per repeated non-map field, declared at
function entry. Counters survive across loop iterations so out-of-order
wire entries for the same field continue past the existing length
without re-scanning.

Profile attributed 6.2% of hello.Person 1KB decode to the `#list + 1`
re-traversal (26-email Person paid 26 list scans per decode).

Bench (Person full decode, msgs/s, median-of-3 vs post-4kj):
1KB +5.0%, 10KB +5.0%, 100KB +7.1%. Encode flat. Tests 745/745.
JIT 37/37, 0 bridges.

beads-tarantool-protobuf-cch
feecf8e0 — Eugene Blikh 3 months ago
codegen: inline 1-byte tag fast path at decode call sites

Hoists wire.decode_tag's 1-byte fast path into every generated
M.X_decode while-loop, falling back to the helper for multi-byte
tags (field ids > 15). The 1-byte case covers every protobuf field
with id 1..15 and is the dominant decode dispatch in real payloads.

Header now localizes string.byte, bit.band, and bit.rshift so the
inlined ops compile to straight local calls.

Bench (Person full decode, msgs/s, median-of-3 vs proper post-h8v
3-run baseline): 10B +14.7%, 100B +8.9%, 1KB +7.5%, 10KB +7.0%,
100KB +8.5%. Full encode is flat to small (-0.1% to -2.6%) at large
sizes, plausibly from header-upvalue layout. JIT trace gate: 37/37,
all bridges still 0. Tests: 745/745.

Also documented in bench/PERF_LOG.md, including the methodology
note that h8v's earlier numbers used single-run baselines and are
therefore ~3-5% optimistic; medians-of-3 are the standard now.

beads-tarantool-protobuf-4kj
c85386b1 — Eugene Blikh 3 months ago
bench: record gcy (inline nested-message decode) post-mortem

Implemented and benchmarked the inline-nested-decode plan from
tarantool-protobuf-gcy. Test suite and JIT gate both pass, but
median-of-3 bench shows 3-8% regressions on Person 1KB/10KB/100KB
encode AND decode. Profile's "100% interpreter bail at Address_decode
call" turned out to be a vl trace-attribution artifact; LuaJIT was
already handling the call well.

Lesson recorded in bench/PERF_LOG.md so the next person who reads the
profile entry knows the obvious-looking inline transformation does
not deliver here. Code change reverted; only the writeup lands.

beads-tarantool-protobuf-gcy
9ee21c09 — Eugene Blikh 3 months ago
codegen: inline 1-byte varint length prefix at every LEN emit site

Eliminates the wire.encode_varint(#body) call + dispatch for every
length-delimited field in mode=full codegen. Profile flagged the
out[n] = wire.encode_varint(#_b) line as ~33% of hello.Person 1KB
encode time, with another ~17% in encode_varint dispatch — together
~50% of encode time. Lifting the 1-byte fast path (the dominant case
for proto strings and small message bodies) to the call site removes
the function frame entirely for lengths < 128.

Applied at every LEN emit site: singular/repeated message body,
singular/repeated string|bytes, packed scalar bundle, packed enum
bundle, map entry. Map value pieces (emitMapPiece message branch)
left as-is — they sit inside a single slot assignment that would
require a deeper restructure, and maps are not on the current hot
benchmark.

Results (hello.Person full encode, msgs/s): 10B +6.9%, 100B +7.9%,
1KB +25.7%, 10KB +48.1%, 100KB +31.9%. Decode flat (unchanged path).
Runtime mode flat (descriptor dispatch still calls encode_varint).
JIT trace gate: 37/37. Test suite: 745/745.

Bench history saved to bench/PERF_LOG.md with full numbers and the
workflow this iteration follows.

beads-tarantool-protobuf-h8v