Skip to content

perf: Frame prefixed keys directly instead of via a temporary copy - #2862

Open
iliaal wants to merge 1 commit into
phpredis:developfrom
iliaal:perf/prefix-key-direct-append
Open

perf: Frame prefixed keys directly instead of via a temporary copy#2862
iliaal wants to merge 1 commit into
phpredis:developfrom
iliaal:perf/prefix-key-direct-append

Conversation

@iliaal

@iliaal iliaal commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

When OPT_PREFIX is set, redis_cmd_append_sstr_key built a temporary prefixed key (emalloc + 2 memcpy), appended it into the command buffer (a third copy), then freed it. Outside cluster mode, this frames the prefix and key as one RESP bulk argument directly into the buffer instead, dropping the temporary allocation and a copy for every key. The cluster path (slot != NULL) keeps the contiguous key, since cluster_hash_key must see prefix and key together (a hash tag can straddle the boundary). The spprintf 'k' case now delegates to the same helper.

Verified on PHP 8.4: on-wire key equals prefix+key across string/binary/empty keys, multi-key commands, RENAME, serializer+prefix, and the no-prefix regression path; testPrefix and 6 other suite methods pass; no leaks. Byte-equivalence and cluster-path safety also reviewed independently.

When OPT_PREFIX is set, redis_cmd_append_sstr_key built the prefixed key
with redis_key_prefix (emalloc + two memcpy), used it, appended it into
the command smart_string (a third copy), then freed it. Outside cluster
mode the contiguous prefixed key is only needed for that append, so frame
the prefix and key as a single RESP bulk argument directly into the
command buffer via a new two-segment helper, dropping the temporary
allocation and one full-key copy per key. This runs for every key in
GET/SET/H*/MGET/INCR/etc. whenever a prefix is configured.

The cluster path (slot != NULL) is unchanged: it still builds the
contiguous key because cluster_hash_key must see prefix and key together
(a hash tag can span the boundary). The spprintf 'k' case, which
duplicated this logic, now delegates to redis_cmd_append_sstr_key and so
picks up the same fast path; 'K' already delegated.

Verified on PHP 8.4: on-wire key equals prefix+key across SET/GET, HSET,
RPUSH, SADD, ZADD, MSET/MGET, EXISTS/DEL multi-key, EXPIRE, RENAME (both
keys), binary and empty keys, serializer+prefix, and the no-prefix
regression path; no leaks under report_memleaks; testPrefix/testSetGet/
testKeys/testHashes/testMSetNX/testRename/testMulti pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant