goadesign / goa

🌟 Goa: Elevate Go API development! 🚀 Streamlined design, automatic code generation, and seamless HTTP/gRPC support. ✨
https://goa.design
MIT License
5.62k stars 557 forks source link

Generated server code parses query parameters repeatedly #3505

Closed duckbrain closed 4 months ago

duckbrain commented 4 months ago

When goa generates server code for query parameters, it checks each parameter one after another with code that looks something like this:

        advRaw := r.URL.Query().Get("adv")
        if advRaw != "" {
            adv = &advRaw
        }
        afRaw := r.URL.Query().Get("af")
        if afRaw != "" {
            af = &afRaw
        }
        apbndlRaw := r.URL.Query().Get("apbndl")
        if apbndlRaw != "" {
            apbndl = &apbndlRaw
        }

The problem with this code, is that r.URL.Query() is called repeatedly. Each call parses r.URL.RawQuery into a url.Values map. One values is pulled from the map, then the map is left to be garbage collected. It'd be much better to parse the query parameters once and store the result in a variable to be referenced for each query parameter to check.

In a test on one of our projects on an endpoint with many query parameters defined, this resulted in 24.11GB (41.4%) of heap allocations (using the alloc profile) coming from calls to url.(*URL).Query within the generated server.DecodeXXXXRequest.func1.

raphael commented 4 months ago

That makes sense, thank you for the contribution!