Skip to content

Commit

Permalink
Merge pull request graphql-go#682 from adelsz/faster-printer-print
Browse files Browse the repository at this point in the history
Faster printer.Print
  • Loading branch information
chris-ramon authored Oct 12, 2024
2 parents f2b39ca + 15d7510 commit a546af7
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 8 deletions.
24 changes: 24 additions & 0 deletions language/printer/printer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,27 @@ func TestPrinter_CorrectlyPrintsStringArgumentsWithProperQuoting(t *testing.T) {
t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, results))
}
}

func BenchmarkPrint(b *testing.B) {
q, err := ioutil.ReadFile("../../kitchen-sink.graphql")
if err != nil {
b.Fatalf("unable to load kitchen-sink.graphql")
}

query := string(q)

astDoc, err := parser.Parse(parser.ParseParams{
Source: query,
Options: parser.ParseOptions{
NoLocation: true,
},
})
if err != nil {
b.Fatalf("Parse failed: %v", err)
}

b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = printer.Print(astDoc)
}
}
64 changes: 56 additions & 8 deletions language/visitor/visitor.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package visitor

import (
"encoding/json"
"reflect"

"fmt"
"github.com/graphql-go/graphql/language/ast"
"github.com/graphql-go/graphql/language/typeInfo"
"reflect"
)

const (
Expand Down Expand Up @@ -446,14 +445,63 @@ func convertMap(src interface{}) (dest map[string]interface{}, err error) {
if src == nil {
return
}
var bts []byte
if bts, err = json.Marshal(src); err != nil {

// return if src is already a map
dest, ok := src.(map[string]interface{})
if ok {
return
}
if err = json.Unmarshal(bts, &dest); err != nil {
return

outputMap := make(map[string]interface{})
val := reflect.ValueOf(src)

// Dereference pointer if necessary
if val.Kind() == reflect.Ptr {
if val.IsNil() {
return nil, fmt.Errorf("input is a nil pointer")
}
val = val.Elem()
}

if val.Kind() != reflect.Struct {
return nil, fmt.Errorf("input is not a struct or pointer to struct")
}
return

typ := val.Type()
for i := 0; i < val.NumField(); i++ {
field := val.Field(i)
fieldName := typ.Field(i).Name

switch field.Kind() {
case reflect.Ptr:
if field.IsNil() {
outputMap[fieldName] = nil
} else {
nestedMap, err := convertMap(field.Interface())
if err != nil {
return nil, err
}
outputMap[fieldName] = nestedMap
}
case reflect.Struct:
nestedMap, err := convertMap(field.Interface())
if err != nil {
return nil, err
}
outputMap[fieldName] = nestedMap
case reflect.Interface:
if field.IsNil() {
outputMap[fieldName] = nil
} else {
concreteValue := field.Elem()
outputMap[fieldName], _ = convertMap(concreteValue.Interface())
}
default:
outputMap[fieldName] = field.Interface()
}
}

return outputMap, nil
}

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

0 comments on commit a546af7

Please sign in to comment.