Skip to content

Commit a546af7

Browse files
authored
Merge pull request #682 from adelsz/faster-printer-print
Faster printer.Print
2 parents f2b39ca + 15d7510 commit a546af7

File tree

2 files changed

+80
-8
lines changed

2 files changed

+80
-8
lines changed

language/printer/printer_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,27 @@ func TestPrinter_CorrectlyPrintsStringArgumentsWithProperQuoting(t *testing.T) {
200200
t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, results))
201201
}
202202
}
203+
204+
func BenchmarkPrint(b *testing.B) {
205+
q, err := ioutil.ReadFile("../../kitchen-sink.graphql")
206+
if err != nil {
207+
b.Fatalf("unable to load kitchen-sink.graphql")
208+
}
209+
210+
query := string(q)
211+
212+
astDoc, err := parser.Parse(parser.ParseParams{
213+
Source: query,
214+
Options: parser.ParseOptions{
215+
NoLocation: true,
216+
},
217+
})
218+
if err != nil {
219+
b.Fatalf("Parse failed: %v", err)
220+
}
221+
222+
b.ResetTimer()
223+
for i := 0; i < b.N; i++ {
224+
_ = printer.Print(astDoc)
225+
}
226+
}

language/visitor/visitor.go

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package visitor
22

33
import (
4-
"encoding/json"
5-
"reflect"
6-
4+
"fmt"
75
"github.com/graphql-go/graphql/language/ast"
86
"github.com/graphql-go/graphql/language/typeInfo"
7+
"reflect"
98
)
109

1110
const (
@@ -446,14 +445,63 @@ func convertMap(src interface{}) (dest map[string]interface{}, err error) {
446445
if src == nil {
447446
return
448447
}
449-
var bts []byte
450-
if bts, err = json.Marshal(src); err != nil {
448+
449+
// return if src is already a map
450+
dest, ok := src.(map[string]interface{})
451+
if ok {
451452
return
452453
}
453-
if err = json.Unmarshal(bts, &dest); err != nil {
454-
return
454+
455+
outputMap := make(map[string]interface{})
456+
val := reflect.ValueOf(src)
457+
458+
// Dereference pointer if necessary
459+
if val.Kind() == reflect.Ptr {
460+
if val.IsNil() {
461+
return nil, fmt.Errorf("input is a nil pointer")
462+
}
463+
val = val.Elem()
464+
}
465+
466+
if val.Kind() != reflect.Struct {
467+
return nil, fmt.Errorf("input is not a struct or pointer to struct")
455468
}
456-
return
469+
470+
typ := val.Type()
471+
for i := 0; i < val.NumField(); i++ {
472+
field := val.Field(i)
473+
fieldName := typ.Field(i).Name
474+
475+
switch field.Kind() {
476+
case reflect.Ptr:
477+
if field.IsNil() {
478+
outputMap[fieldName] = nil
479+
} else {
480+
nestedMap, err := convertMap(field.Interface())
481+
if err != nil {
482+
return nil, err
483+
}
484+
outputMap[fieldName] = nestedMap
485+
}
486+
case reflect.Struct:
487+
nestedMap, err := convertMap(field.Interface())
488+
if err != nil {
489+
return nil, err
490+
}
491+
outputMap[fieldName] = nestedMap
492+
case reflect.Interface:
493+
if field.IsNil() {
494+
outputMap[fieldName] = nil
495+
} else {
496+
concreteValue := field.Elem()
497+
outputMap[fieldName], _ = convertMap(concreteValue.Interface())
498+
}
499+
default:
500+
outputMap[fieldName] = field.Interface()
501+
}
502+
}
503+
504+
return outputMap, nil
457505
}
458506

459507
// get value by key from struct | slice | map | wrap(prev)

0 commit comments

Comments
 (0)