From b0ffa22a8a06fb912b5ef36260b2025bf66e1356 Mon Sep 17 00:00:00 2001 From: Adam Scarr Date: Tue, 27 Nov 2018 19:27:19 +1100 Subject: [PATCH] Remove strconv.Quote call in hot path to avoid some allocs 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 --- graphql/jsonw.go | 3 +-- graphql/string.go | 59 +++++++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/graphql/jsonw.go b/graphql/jsonw.go index c112444a7e..c087f63bd0 100644 --- a/graphql/jsonw.go +++ b/graphql/jsonw.go @@ -2,7 +2,6 @@ package graphql import ( "io" - "strconv" ) var nullLit = []byte(`null`) @@ -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) } diff --git a/graphql/string.go b/graphql/string.go index d5fb32947d..7c1b7d9577 100644 --- a/graphql/string.go +++ b/graphql/string.go @@ -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: