graphql-go / graphql

An implementation of GraphQL for Go / Golang
MIT License
9.94k stars 842 forks source link

Printing GraphQL documents is slow #674

Closed jturkel closed 1 month ago

jturkel commented 1 year ago

We did some benchmarking of a possible GraphQL gateway built on top of this library and noticed that serializing queries takes hundreds of milliseconds. Here's a benchmark that demonstrate the issue and compares results to wundergraph/graphql-go-tools:

package main

import (
    "os"
    "testing"

    "github.com/graphql-go/graphql/language/parser"
    "github.com/graphql-go/graphql/language/printer"

    "github.com/wundergraph/graphql-go-tools/pkg/astparser"
    "github.com/wundergraph/graphql-go-tools/pkg/astprinter"
)

func BenchmarkPrinter_GraphQLGo(b *testing.B) {
    query, err := os.ReadFile("benchmark_query.graphql")
    if err != nil {
        panic(err)
    }

    document, err := parser.Parse(parser.ParseParams{
        Source: string(query),
    })
    if err != nil {
        panic(err)
    }

    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        if printer.Print(document) == "" {
            panic("print failed")
        }
    }
}

func BenchmarkPrinter_GraphQLGoTools(b *testing.B) {
    query, err := os.ReadFile("benchmark_query.graphql")
    if err != nil {
        panic(err)
    }

    document, report := astparser.ParseGraphqlDocumentBytes(query)
    if report.HasErrors() {
        panic(report.Error())
    }

    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        _, err := astprinter.PrintString(&document, nil)
        if err != nil {
            panic(err)
        }
    }
}

The benchmark query can be found here and is an anonymized version of a real query in our system. On average graphql-go/graphql takes 303ms to print this query and wundergraph/graphql-go-tools takes 0.018 ms.

adelsz commented 1 year ago

We had just run into the same issue. Printer is terribly slow.