Skip to content

Commit

Permalink
internal/transport: optimize grpc-message encoding/decoding (#5654)
Browse files Browse the repository at this point in the history
  • Loading branch information
tklauser authored Oct 4, 2022
1 parent be4b63b commit 1451c62
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 11 deletions.
21 changes: 10 additions & 11 deletions internal/transport/http_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ package transport

import (
"bufio"
"bytes"
"encoding/base64"
"fmt"
"io"
Expand Down Expand Up @@ -251,13 +250,13 @@ func encodeGrpcMessage(msg string) string {
}

func encodeGrpcMessageUnchecked(msg string) string {
var buf bytes.Buffer
var sb strings.Builder
for len(msg) > 0 {
r, size := utf8.DecodeRuneInString(msg)
for _, b := range []byte(string(r)) {
if size > 1 {
// If size > 1, r is not ascii. Always do percent encoding.
buf.WriteString(fmt.Sprintf("%%%02X", b))
fmt.Fprintf(&sb, "%%%02X", b)
continue
}

Expand All @@ -266,14 +265,14 @@ func encodeGrpcMessageUnchecked(msg string) string {
//
// fmt.Sprintf("%%%02X", utf8.RuneError) gives "%FFFD".
if b >= spaceByte && b <= tildeByte && b != percentByte {
buf.WriteByte(b)
sb.WriteByte(b)
} else {
buf.WriteString(fmt.Sprintf("%%%02X", b))
fmt.Fprintf(&sb, "%%%02X", b)
}
}
msg = msg[size:]
}
return buf.String()
return sb.String()
}

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

func decodeGrpcMessageUnchecked(msg string) string {
var buf bytes.Buffer
var sb strings.Builder
lenMsg := len(msg)
for i := 0; i < lenMsg; i++ {
c := msg[i]
if c == percentByte && i+2 < lenMsg {
parsed, err := strconv.ParseUint(msg[i+1:i+3], 16, 8)
if err != nil {
buf.WriteByte(c)
sb.WriteByte(c)
} else {
buf.WriteByte(byte(parsed))
sb.WriteByte(byte(parsed))
i += 2
}
} else {
buf.WriteByte(c)
sb.WriteByte(c)
}
}
return buf.String()
return sb.String()
}

type bufWriter struct {
Expand Down
24 changes: 24 additions & 0 deletions internal/transport/http_util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,3 +214,27 @@ func (s) TestParseDialTarget(t *testing.T) {
}
}
}

func BenchmarkDecodeGrpcMessage(b *testing.B) {
input := "Hello, %E4%B8%96%E7%95%8C"
want := "Hello, 世界"
b.ReportAllocs()
for i := 0; i < b.N; i++ {
got := decodeGrpcMessage(input)
if got != want {
b.Fatalf("decodeGrpcMessage(%q) = %s, want %s", input, got, want)
}
}
}

func BenchmarkEncodeGrpcMessage(b *testing.B) {
input := "Hello, 世界"
want := "Hello, %E4%B8%96%E7%95%8C"
b.ReportAllocs()
for i := 0; i < b.N; i++ {
got := encodeGrpcMessage(input)
if got != want {
b.Fatalf("encodeGrpcMessage(%q) = %s, want %s", input, got, want)
}
}
}

0 comments on commit 1451c62

Please sign in to comment.