1
0
mirror of https://github.com/redis/go-redis.git synced 2026-10-24 07:59:20 +03:00
Files
go-redis/csc_cachekey_test.go
Nedyalko Dyakov ac839125d6 perf(csc): pool the cache-key scratch, fuse the namespace (#4036)
* perf(csc): pool the cache-key scratch, fuse the namespace

Building a cache key was 32% of all bytes allocated on the cached read
path. Every call heap-allocated a bytes.Buffer, a proto.Writer (which
itself allocates two 64-byte scratch slices, 16.2% of all bytes on its
own), grew the buffer, and copied it out with String() -- and then the
caller did prefix+key for a second full copy of every key.

Only the final String() is inherent: the key is retained, the scratch
is not. Pool the buffer and writer, and write the namespace into the
buffer before the args so one String() yields the namespaced key
directly. Five allocations become one.

proto.Writer gains Reset so a writer can be re-targeted rather than
reallocated.

Total bytes allocated 9,858MB -> 6,915MB (-30%); NewWriter,
buildCacheKey, cscNamespacedKey and Buffer.grow leave the profile.
Throughput +8.7% at 256 callers, +13.6% at 1024, +37.4% at 10k
invalidations/s, with p99 down in every cell.

* fix(csc): move the un-namespaced cache-key helper to tests

buildCacheKey lost its last non-test caller when the cached read path
moved to buildCacheKeyNS, which builds the namespaced key in one
allocation. golangci-lint runs with run.tests=false, so its remaining
callers in csc_test.go do not count and the unused check fails.

Move it to csc_cachekey_test.go: production keeps a single entry point
and the tests keep the un-namespaced form they assert on.
2026-10-01 14:49:53 +03:00

13 lines
515 B
Go

package redis
// buildCacheKey renders a command's cache key with no namespace.
//
// Production code always namespaces the key, and builds it in one allocation
// via buildCacheKeyNS, so this un-namespaced form has no non-test caller. It
// lives here rather than in csc_commands.go so the production file has a
// single entry point and the linter's unused check stays clean (the repo runs
// golangci-lint with run.tests=false).
func buildCacheKey(cmd Cmder) (string, bool) {
return buildCacheKeyNS(cmd, "")
}