-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve transport.Post Do method #3373
Conversation
resp := exec.DispatchError(ctx, gqlerror.List{gqlErr}) | ||
writeJson(w, resp) | ||
return | ||
} | ||
|
||
bodyReader := io.NopCloser(strings.NewReader(bodyString)) | ||
if err = jsonDecode(bodyReader, ¶ms); err != nil { | ||
bodyReader := bytes.NewReader(bodyBytes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little nervous about removing the io.NopCloser
here. We used to have quite a few issues with accidentally closing io.Reader
more than once, and it was pretty hard to track down.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, nevermind. It looks like that doesn't apply at all here (or at least it doesn't anymore). That was a different part of the codebase.
I greatly appreciate you looking into performance improvements, but I want to ask how you have picked which places to optimize here and in your other PR. It would be extremely valuable to the entire project to identify where the biggest source of allocations or CPU usage are coming from during a realistic load scenario. It may be that you have done that, but even if this is the most important place, I would like to hear what you found were second or third and why, as others in the community may be able to help on those. Also, I'm not sure how far to take performance improvements in this area at the expense of readability and maintainability. For instance, io.ReadAll is much more readable than using io.Copy, but it does produce more allocations. Make up a 10 MB text file:
Output:
Or take for example this article: https://klotzandrew.com/blog/speeding-up-json-processing-in-go/
But it can definitely be made faster and allocate much less at the expense of complicating it as in the article. It is worth it if the gains are worth it in comparison to everything else, but if it's a small part of the overall, then it's not worth it. With this PR, I can't tell how much your performance improvement in this area relates to the overall CPU/memory performance. If you have already worked that out, I would love it if you could share that. |
I'm merging the PR here, but I would still appreciate someone sharing an analysis of the most performance critical areas of gqlgen runtime. |
@StevenACoffman I will continue to share insights on gqlgen runtime bottlenecks in this issue. |
Description
related
This PR optimizes the
Do
method intransport.Post
by addressing memory allocation inefficiencies. Specifically:[]byte
tostring
conversions in theDo
method, which were causing additional memory allocations.sync.Pool
forgraphql.RawParams
to enable memory reuse, reducing overall allocations.These changes aim to improve the performance of the gqlgen server, especially in high-throughput scenarios.
Related Issue
Resolves #3372 (replace with actual issue link)
Benchmark
I took benchmark simple code 5 times.
schema is generated project initizalization.
resolver implementation
Result
Before
After
Checklist
I have: