Skip to content

Commit

Permalink
Remove strconv.Quote call in hot path to avoid some allocs
Browse files Browse the repository at this point in the history
go test -benchtime=5s -bench=. -benchmem
goos: linux
goarch: amd64
pkg: github.com/99designs/gqlgen/example/starwars
BenchmarkSimpleQueryNoArgs-8      200000             32125 ns/op            6277 B/op        118 allocs/op
PASS
ok      github.com/99designs/gqlgen/example/starwars    9.768s
  • Loading branch information
vektah committed Dec 8, 2018
1 parent 2cf5a5b commit b0ffa22
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 29 deletions.
3 changes: 1 addition & 2 deletions graphql/jsonw.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package graphql

import (
"io"
"strconv"
)

var nullLit = []byte(`null`)
Expand Down Expand Up @@ -56,7 +55,7 @@ func (m *OrderedMap) MarshalGQL(writer io.Writer) {
if i != 0 {
writer.Write(comma)
}
io.WriteString(writer, strconv.Quote(key))
writeQuotedString(writer, key)
writer.Write(colon)
m.Values[i].MarshalGQL(writer)
}
Expand Down
59 changes: 32 additions & 27 deletions graphql/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,42 @@ const encodeHex = "0123456789ABCDEF"

func MarshalString(s string) Marshaler {
return WriterFunc(func(w io.Writer) {
start := 0
io.WriteString(w, `"`)

for i, c := range s {
if c < 0x20 || c == '\\' || c == '"' {
io.WriteString(w, s[start:i])

switch c {
case '\t':
io.WriteString(w, `\t`)
case '\r':
io.WriteString(w, `\r`)
case '\n':
io.WriteString(w, `\n`)
case '\\':
io.WriteString(w, `\\`)
case '"':
io.WriteString(w, `\"`)
default:
io.WriteString(w, `\u00`)
w.Write([]byte{encodeHex[c>>4], encodeHex[c&0xf]})
}

start = i + 1
writeQuotedString(w, s)
})
}

func writeQuotedString(w io.Writer, s string) {
start := 0
io.WriteString(w, `"`)

for i, c := range s {
if c < 0x20 || c == '\\' || c == '"' {
io.WriteString(w, s[start:i])

switch c {
case '\t':
io.WriteString(w, `\t`)
case '\r':
io.WriteString(w, `\r`)
case '\n':
io.WriteString(w, `\n`)
case '\\':
io.WriteString(w, `\\`)
case '"':
io.WriteString(w, `\"`)
default:
io.WriteString(w, `\u00`)
w.Write([]byte{encodeHex[c>>4], encodeHex[c&0xf]})
}

start = i + 1
}
}

io.WriteString(w, s[start:])
io.WriteString(w, `"`)
})
io.WriteString(w, s[start:])
io.WriteString(w, `"`)
}

func UnmarshalString(v interface{}) (string, error) {
switch v := v.(type) {
case string:
Expand Down

0 comments on commit b0ffa22

Please sign in to comment.