graphql-go / graphql

An implementation of GraphQL for Go / Golang
MIT License
9.82k stars 836 forks source link

Faster printer.Print #682

Open adelsz opened 8 months ago

adelsz commented 8 months ago

In our project we do thousands of printer.Print calls per second, so its performance is critical for us.

As it is, printer.Print is rather slow, see issue #674 for some comparisons. This is caused by its use of json.Marshal and json.Unmarshal as a way of converting interfaces to map[string]interface{} in the convertMap method.

This PR replaces the JSON logic with a custom, reflection based converter instead.

It also adds a benchmark to measure the performance impact.

Before the changes:

goos: darwin
goarch: arm64
pkg: github.com/graphql-go/graphql/language/printer
BenchmarkPrint
BenchmarkPrint-10            604       1965835 ns/op
PASS

After the changes:

goos: darwin
goarch: arm64
pkg: github.com/graphql-go/graphql/language/printer
BenchmarkPrint
BenchmarkPrint-10           4900        235592 ns/op
PASS

Roughly a 10x speedup. There might be some edge-cases I have missed, but looks like convertMap conforms to the behavior of its previous version.

Fixes #674

coveralls commented 8 months ago

Coverage Status

coverage: 92.051%. remained the same when pulling 732b137605d9211d9288d47eebb585d7fabe8950 on adelsz:faster-printer-print into 4ebf270b92df8ca6b2eb2ed97e595e642dee9b0a on graphql-go:master.