Skip to content

Commit 1451c62

Browse files
authored
internal/transport: optimize grpc-message encoding/decoding (#5654)
1 parent be4b63b commit 1451c62

File tree

2 files changed

+34
-11
lines changed

2 files changed

+34
-11
lines changed

internal/transport/http_util.go

+10-11
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ package transport
2020

2121
import (
2222
"bufio"
23-
"bytes"
2423
"encoding/base64"
2524
"fmt"
2625
"io"
@@ -251,13 +250,13 @@ func encodeGrpcMessage(msg string) string {
251250
}
252251

253252
func encodeGrpcMessageUnchecked(msg string) string {
254-
var buf bytes.Buffer
253+
var sb strings.Builder
255254
for len(msg) > 0 {
256255
r, size := utf8.DecodeRuneInString(msg)
257256
for _, b := range []byte(string(r)) {
258257
if size > 1 {
259258
// If size > 1, r is not ascii. Always do percent encoding.
260-
buf.WriteString(fmt.Sprintf("%%%02X", b))
259+
fmt.Fprintf(&sb, "%%%02X", b)
261260
continue
262261
}
263262

@@ -266,14 +265,14 @@ func encodeGrpcMessageUnchecked(msg string) string {
266265
//
267266
// fmt.Sprintf("%%%02X", utf8.RuneError) gives "%FFFD".
268267
if b >= spaceByte && b <= tildeByte && b != percentByte {
269-
buf.WriteByte(b)
268+
sb.WriteByte(b)
270269
} else {
271-
buf.WriteString(fmt.Sprintf("%%%02X", b))
270+
fmt.Fprintf(&sb, "%%%02X", b)
272271
}
273272
}
274273
msg = msg[size:]
275274
}
276-
return buf.String()
275+
return sb.String()
277276
}
278277

279278
// decodeGrpcMessage decodes the msg encoded by encodeGrpcMessage.
@@ -291,23 +290,23 @@ func decodeGrpcMessage(msg string) string {
291290
}
292291

293292
func decodeGrpcMessageUnchecked(msg string) string {
294-
var buf bytes.Buffer
293+
var sb strings.Builder
295294
lenMsg := len(msg)
296295
for i := 0; i < lenMsg; i++ {
297296
c := msg[i]
298297
if c == percentByte && i+2 < lenMsg {
299298
parsed, err := strconv.ParseUint(msg[i+1:i+3], 16, 8)
300299
if err != nil {
301-
buf.WriteByte(c)
300+
sb.WriteByte(c)
302301
} else {
303-
buf.WriteByte(byte(parsed))
302+
sb.WriteByte(byte(parsed))
304303
i += 2
305304
}
306305
} else {
307-
buf.WriteByte(c)
306+
sb.WriteByte(c)
308307
}
309308
}
310-
return buf.String()
309+
return sb.String()
311310
}
312311

313312
type bufWriter struct {

internal/transport/http_util_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,27 @@ func (s) TestParseDialTarget(t *testing.T) {
214214
}
215215
}
216216
}
217+
218+
func BenchmarkDecodeGrpcMessage(b *testing.B) {
219+
input := "Hello, %E4%B8%96%E7%95%8C"
220+
want := "Hello, 世界"
221+
b.ReportAllocs()
222+
for i := 0; i < b.N; i++ {
223+
got := decodeGrpcMessage(input)
224+
if got != want {
225+
b.Fatalf("decodeGrpcMessage(%q) = %s, want %s", input, got, want)
226+
}
227+
}
228+
}
229+
230+
func BenchmarkEncodeGrpcMessage(b *testing.B) {
231+
input := "Hello, 世界"
232+
want := "Hello, %E4%B8%96%E7%95%8C"
233+
b.ReportAllocs()
234+
for i := 0; i < b.N; i++ {
235+
got := encodeGrpcMessage(input)
236+
if got != want {
237+
b.Fatalf("encodeGrpcMessage(%q) = %s, want %s", input, got, want)
238+
}
239+
}
240+
}

0 commit comments

Comments
 (0)