perf(resp): encode a three-argument RESP command with one Appendf

encodeCommands wrote one fmt.Appendf call per header and per argument. A
counter pipeline is almost entirely INCRBY and EXPIRE commands, which
carry three arguments each, so a metered request paid four Appendf calls
for every counter it wrote.

A command with exactly three arguments now goes through one Appendf with
the whole template. Every other arity keeps the per-argument loop. The
bytes on the wire do not change.

A new test compares arities two, three, four and five against the
previous encoder, so a wrong arity guard cannot emit a three-argument
header for a longer command.

Measured under yaegi as above: about 3% fewer bytes allocated per
request.

Claude-Session: https://claude.ai/code/session_01KwtV5ecajCrftcf8TkfPad
This commit is contained in:
2026-09-17 20:59:11 +01:00
parent 4fb5315bb3
commit 96b1a27ba5
2 changed files with 42 additions and 0 deletions
+14
View File
@@ -439,9 +439,23 @@ func closeConn(pc *respConn) {
// under yaegi v0.16.1: cheaper than either presizing (the interpreted size
// loop cost more than native slice regrowth) or appending raw bytes
// directly (append with a string operand copies it under yaegi).
//
// A 3-argument command — INCRBY key delta or EXPIRE key seconds, this
// client's two hottest commands by far (every counter increment sends
// one, sometimes both) — takes a fast path instead: one fmt.Appendf call
// building the whole "*3\r\n$len\r\narg\r\n..." frame at once, rather than
// one header call plus 3 more per-argument calls. Measured under yaegi
// v0.16.1 on the counter-increment pipeline this dominates: about 3%
// fewer bytes per request. Any other argument count keeps the general
// loop below — wire bytes are identical either way.
func encodeCommands(cmds [][]string) []byte {
var dst []byte
for _, args := range cmds {
if len(args) == 3 {
dst = fmt.Appendf(dst, "*3\r\n$%d\r\n%s\r\n$%d\r\n%s\r\n$%d\r\n%s\r\n",
len(args[0]), args[0], len(args[1]), args[1], len(args[2]), args[2])
continue
}
dst = fmt.Appendf(dst, "*%d\r\n", len(args))
for _, a := range args {
dst = fmt.Appendf(dst, "$%d\r\n%s\r\n", len(a), a)