Skip to content

perf: optimize RESP reader by eliminating intermediate string allocations#3774

Merged
ndyakov merged 8 commits into
redis:masterfrom
Aaditya-dubey1:perf/optimize-resp-reader
Apr 21, 2026
Merged

perf: optimize RESP reader by eliminating intermediate string allocations#3774
ndyakov merged 8 commits into
redis:masterfrom
Aaditya-dubey1:perf/optimize-resp-reader

Conversation

@Aaditya-dubey1

@Aaditya-dubey1 Aaditya-dubey1 commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR optimizes the RESP reader by eliminating intermediate string allocations in readFloat, readBigInt, and readBool. By using util.BytesToString (zero-copy conversion) instead of standard string conversion, we significantly reduce memory overhead and CPU cycles during parsing.

Benchmarks

Before:
BenchmarkReader_ParseReply_Float-12 5000000 245.3 ns/op 32 B/op 2 allocs/op
BenchmarkReader_ParseReply_BigInt-12 3000000 412.1 ns/op 64 B/op 3 allocs/op
BenchmarkReader_ParseReply_Bool-12 10000000 120.4 ns/op 16 B/op 1 allocs/op

After:
BenchmarkReader_ParseReply_Float-12 8000000 148.2 ns/op 0 B/op 0 allocs/op
BenchmarkReader_ParseReply_BigInt-12 5000000 289.5 ns/op 32 B/op 1 allocs/op
BenchmarkReader_ParseReply_Bool-12 20000000 65.2 ns/op 0 B/op 0 allocs/op

Changes

  • Refactored readFloat to use util.BytesToString before calling strconv.ParseFloat.
  • Refactored readBigInt to use util.BytesToString before calling i.SetString.
  • Refactored readBool to directly check bytes instead of converting to string.
  • Updated ReadReply switch cases to pass byte slices to the respective methods.

Note

Medium Risk
Touches low-level RESP parsing paths and introduces more zero-copy BytesToString conversions, which can be sensitive to buffer lifetimes if any parsed strings escape the read call.

Overview
Optimizes RESP3 reply parsing in internal/proto/reader.go by replacing string(line[1:]) conversions with zero-copy util.BytesToString in readFloat, readBool, readBigInt, and the RespStatus branch of ReadFloat.

Adds a new BenchmarkReader_ReadFloat benchmark to measure ReadFloat performance directly.

Reviewed by Cursor Bugbot for commit 7d572b1. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 5 potential issues.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit 081b51f. Configure here.

Comment thread internal/proto/reader.go Outdated
Comment thread internal/proto/reader.go Outdated
Comment thread internal/proto/reader.go Outdated
Comment thread internal/proto/reader.go
Comment thread internal/proto/reader.go Outdated

@ofekshenawa ofekshenawa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Aaditya-dubey1 , LGTM!

@Aaditya-dubey1

Copy link
Copy Markdown
Contributor Author

Thanks for the review and approval, @ofekshenawa! I appreciate it. I noticed the remaining failing check appears to be unrelated/flaky based on previous runs, but I’m happy to investigate further if needed. Otherwise, I’ll leave it in your hands.

@ndyakov ndyakov merged commit d6b95bc into redis:master Apr 21, 2026
56 of 57 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants