Skip to content
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

✨ feat: add support for parameters in content negotiation #2678

Merged
merged 5 commits into from
Nov 7, 2023

Conversation

nickajacks1
Copy link
Member

@nickajacks1 nickajacks1 commented Oct 15, 2023

Attempts to approach the level of support offered by express, but behavior may differ in unusual corner cases.
Some key behaviors from Express that are implemented:

  • If an offer does not have every parameter listed in the given Accept, it is rejected.
  • Parameters do not affect specificity.
  • In a given specificity, more parameters gives greater precedence
  • Parameters are unordered
  • Matching is case-insensitive
  • Surrounding quotes behave strangely (buggy?) in Express, so we only explicitly handle what RFC-9110 allows, which is a quoted value (right side of the equal sign)

Behaviors that were intentionally not implemented:

  • RFC 9110 defines quoted-pairs as octet pairs consisting of a backslash followed by another character. It states that recipients (i.e., servers) must parse quoted pairs as if they were replaced by the octet following the backslash. This changeset does not "ignore" the backslash of quoted-pairs.
    Justification: this only affects functionality when a client escapes a character other than " or \ and the server doesn't account for it in the call to ctx.Accepts. This case is unusual, and RFC 9110 states that clients ought not to do this. See doc comment for paramsMatch for more details.
  • The following case is not handled yet: Accept: */*; param=foo, text/plain; q=0.9, text/plain; param=foo; q=0.8. If the server accepts text/plain and text/plain;param=foo, Express will match "text/plain" because the client explicitly stated they prefer text/plain over text/plain;param=foo even though */*;param=foo has quality 1.0.
    Justification: this behavior was already present in the existing code.

Behaviors were mostly reverse engineered from res.format in Express.

https://www.rfc-editor.org/rfc/rfc9110#name-parameters

More Detail

We redundantly parse parameters for each offer N times instead of just once. Parsing them once in getOffer and passing the results to isAccepted indeed speeds things up, but it slows down the "normal" case (no parameters) more than I would like.

Type of change

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

Checklist:

  • For new functionalities I follow the inspiration of the express js framework and built them similar in usage
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation - /docs/ directory for https://docs.gofiber.io/
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I tried to make my code as fast as possible with as few allocations as possible
  • For new code I have written benchmarks so that they can be analyzed and improved

@welcome
Copy link

welcome bot commented Oct 15, 2023

Thanks for opening this pull request! 🎉 Please check out our contributing guidelines. If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

@nickajacks1
Copy link
Member Author

Ah, I see the CI includes go 1.17, but fuzzing was introduced in 1.18.
Should I remove the fuzz test/move it to a different file with a build constraint so it only runs on 1.18+?

@nickajacks1
Copy link
Member Author

Another thing to note is that this does NOT support RFC 2231, which the stdlib mime package uses for ParseMediaType. mime.ParseMediaType is comparativesly slow and results in more allocations, but might simplify the code significantly (and give fiber RFC 2231 support). To give perspective, it's about 4-5 times slower than getHeaderValParams on my PC. On the other hand, it's on the order of about a microsecond or 2 difference, so it might be worth it. Dunno.

Express's res.format doesn't seem to support it (I did only a very quick test).

@sixcolors
Copy link
Member

sixcolors commented Oct 16, 2023

Express Accepts is very slow. See #2387 and #2486 for some discussion of Accepts and getOffer

My thinking at the time was that most of the spec is unused in practice and it didn’t seem worth it be 10x slower and add allocations.

@sixcolors
Copy link
Member

sixcolors commented Oct 16, 2023

Ah, I see the CI includes go 1.17, but fuzzing was introduced in 1.18. Should I remove the fuzz test/move it to a different file with a build constraint so it only runs on 1.18+?

That seems reasonable. @ReneWerner87 opinion?

@nickajacks1
Copy link
Member Author

Comparison of the existing Benchmark_Ctx_Accepts (with no parameters):

Bench Master

goos: linux
goarch: amd64
pkg: github.com/gofiber/fiber/v2
cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             8462596               135.1 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             8756746               140.4 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             8731399               137.6 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             8783802               136.2 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      6456643               189.8 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      6298566               179.5 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      6333530               191.6 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      6256982               187.6 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              8801590               137.9 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              8277388               141.9 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              8100418               139.4 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              8808856               143.8 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         15855285                71.32 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         16730134                71.76 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         17007514                71.83 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         16997587                71.47 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                        11924296               103.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                        11771935               101.1 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                        11697979               102.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                        11597506               103.0 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         7897026               149.3 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         8071060               149.0 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         7931828               150.1 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         7928245               148.8 ns/op             0 B/op               0 allocs/op

Bench PR

goos: linux
goarch: amd64
pkg: github.com/gofiber/fiber/v2
cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             5346976               228.6 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             5237262               234.3 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             5249563               229.2 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             5278192               228.2 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      4200825               280.5 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      4260450               282.2 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      4240534               285.7 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      4175385               285.1 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              4893387               238.7 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              4945891               237.4 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              4990039               237.4 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              5025672               244.0 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         10382834               114.4 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         10003107               119.1 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         10389516               114.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         10366639               114.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         8250992               146.8 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         8288470               146.3 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         8235308               147.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         8169384               147.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5359063               222.3 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5399341               225.1 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5462929               221.5 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5345566               221.4 ns/op             0 B/op               0 allocs/op

No allocs, but clearly slower. I can look into additional micro-optimizations if a 50% increase in ns/op is unacceptable.
This may be partially attributed to the fact that I am using getSplicedStrList so we can actually handle Accept values where a parameter has a quoted comma (I wish they disallowed that in the spec 😩)
On the other hand, you do get allocs when non-q parameters are present in the Accept header. I could not find a way to avoid allocations.

@ReneWerner87
Copy link
Member

Ah, I see the CI includes go 1.17, but fuzzing was introduced in 1.18. Should I remove the fuzz test/move it to a different file with a build constraint so it only runs on 1.18+?

move to a different file and only run with 1.18+

Comparison of the existing Benchmark_Ctx_Accepts (with no parameters):

Bench Master

goos: linux
goarch: amd64
pkg: github.com/gofiber/fiber/v2
cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             8462596               135.1 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             8756746               140.4 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             8731399               137.6 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             8783802               136.2 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      6456643               189.8 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      6298566               179.5 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      6333530               191.6 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      6256982               187.6 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              8801590               137.9 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              8277388               141.9 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              8100418               139.4 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              8808856               143.8 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         15855285                71.32 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         16730134                71.76 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         17007514                71.83 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         16997587                71.47 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                        11924296               103.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                        11771935               101.1 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                        11697979               102.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                        11597506               103.0 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         7897026               149.3 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         8071060               149.0 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         7931828               150.1 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         7928245               148.8 ns/op             0 B/op               0 allocs/op

Bench PR

goos: linux
goarch: amd64
pkg: github.com/gofiber/fiber/v2
cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             5346976               228.6 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             5237262               234.3 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             5249563               229.2 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             5278192               228.2 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      4200825               280.5 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      4260450               282.2 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      4240534               285.7 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      4175385               285.1 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              4893387               238.7 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              4945891               237.4 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              4990039               237.4 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              5025672               244.0 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         10382834               114.4 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         10003107               119.1 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         10389516               114.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         10366639               114.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         8250992               146.8 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         8288470               146.3 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         8235308               147.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         8169384               147.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5359063               222.3 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5399341               225.1 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5462929               221.5 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5345566               221.4 ns/op             0 B/op               0 allocs/op

No allocs, but clearly slower. I can look into additional micro-optimizations if a 50% increase in ns/op is unacceptable. This may be partially attributed to the fact that I am using getSplicedStrList so we can actually handle Accept values where a parameter has a quoted comma (I wish they disallowed that in the spec 😩) On the other hand, you do get allocs when non-q parameters are present in the Accept header. I could not find a way to avoid allocations.

pls try to optimize it
its to much performance lose for the normal case

@nickajacks1
Copy link
Member Author

nickajacks1 commented Oct 20, 2023

I have made some optimizations to the normal case and params case. I will do another pass later to look into simplifying the code. I'll also try to find more optimizations.
I also still need to move the Fuzz to another file.
I can also revert changes I made to getSplicedStrList.
Still need to write more/better comments

I have found two "sweet spots" in terms of performance so far. For my information, which would be preferred? One is a bit faster for the normal case, and one has a stronger zero-alloc guarantee.

Latest commit (8c7e42d)
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             6232077               201.0 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             6209859               192.4 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             6243812               191.8 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             6373354               191.9 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      4891333               245.2 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      4922055               245.8 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      4890734               242.7 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      4887012               248.7 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              5653296               205.9 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              5849978               201.4 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              6015536               203.7 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              5907765               199.5 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         13672822                89.24 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         13413934                88.35 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         13325611                88.57 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         13614538                87.19 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         9405148               125.2 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         9522655               125.2 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         9591810               125.1 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         9521936               128.2 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5798060               209.5 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5726412               207.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5735221               214.0 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5625366               212.3 ns/op           
Benchmark_Utils_GetOffer-8                       2062950               579.6 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer-8                       2054486               587.3 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer-8                       2063911               624.0 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer-8                       2015850               572.7 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer_WithParams-8            1978866               611.6 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer_WithParams-8            1960564               612.1 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer_WithParams-8            1981094               605.5 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer_WithParams-8            1957227               613.6 ns/op             0 B/op          0 allocs/op
Slightly Faster for normal case, but with allocs when params are used (e0f7591)
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             6245482               177.3 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             6613120               190.5 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             6813296               180.1 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             6118228               179.4 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      5260724               227.8 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      5088298               227.3 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      5166132               237.1 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      5189610               229.0 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              6482988               191.3 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              6337998               187.8 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              6346383               194.7 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              6457539               184.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         13299212                90.25 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         13307904                92.24 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         13089936                89.96 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         13103923                92.27 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         9039381               134.5 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         8809426               139.4 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         9194865               140.3 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                         9066760               140.1 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5760427               204.0 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5820580               206.7 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5659861               206.5 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         5878347               210.2 ns/op             0 B/op               0 allocs/op
Benchmark_Utils_GetOffer-8                       2037672               595.0 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer-8                       2026315               592.6 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer-8                       2054451               592.5 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer-8                       2025991               589.6 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer_WithParams-8            1499647               801.7 ns/op           256 B/op          4 allocs/op
Benchmark_Utils_GetOffer_WithParams-8            1488795               804.2 ns/op           256 B/op          4 allocs/op
Benchmark_Utils_GetOffer_WithParams-8            1488708               811.3 ns/op           256 B/op          4 allocs/op
Benchmark_Utils_GetOffer_WithParams-8            1450987               844.3 ns/op           256 B/op          4 allocs/op

@nickajacks1
Copy link
Member Author

For my information, which would be preferred? One is a bit faster for the normal case, and one has a stronger zero-alloc guarantee.

No need to answer, I got better results, still keeping zero allocs.

Bench
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             7169959               170.9 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             7224782               168.7 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             6738418               164.9 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8             7261536               175.3 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      5267988               221.0 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      5458422               220.8 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      5435494               226.5 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8      5369880               225.5 ns/op             0 B/op          0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              6602116               184.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              6583650               181.7 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              6886975               169.5 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8              6558074               177.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         15245247                78.27 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         15686019                78.51 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         15899508                81.79 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                         15357286                77.00 ns/op            0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                        10913581               109.4 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                        10625037               116.0 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                        11107549               108.7 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                        10941987               109.0 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         6660972               180.5 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         6843264               176.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         6521276               176.6 ns/op             0 B/op               0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                         6834860               178.8 ns/op             0 B/op               0 allocs/op
Benchmark_Utils_GetOffer-8                       2259598               537.2 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer-8                       2277696               526.9 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer-8                       2231707               532.8 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer-8                       2313021               529.3 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer_WithParams-8            2024922               587.8 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer_WithParams-8            2041173               585.1 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer_WithParams-8            2037265               600.4 ns/op             0 B/op          0 allocs/op
Benchmark_Utils_GetOffer_WithParams-8            2004532               585.5 ns/op             0 B/op          0 allocs/op

Still a bit worse than master, but much better than before. I'd imagine I'm beginning to approach the limit of how optimized the new code can get.

I will do another look-over later for further polish. If this PR seems like it might be mergeable, I'll start looking at updating the docs.
@ReneWerner87 I copied validHeaderFieldByte from net/textproto with the comment
// Function copied from net/textproto/reader.go
Is that sufficient, or does there need to be more attribution somewhere?

@sixcolors
Copy link
Member

I won’t have time to review until early next week.

@gaby
Copy link
Member

gaby commented Oct 22, 2023

@nickajacks1 Why copy validHeaderFieldByte instead of using it from net/textproto ?

@gaby
Copy link
Member

gaby commented Oct 22, 2023

@nickajacks1 Why copy validHeaderFieldByte instead of using it from net/textproto ?

There's no valid reason to be copying a function from go native libraries. It that function gets changed/fixed we would miss those changes.

Original is here https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L663 please import that one

@nickajacks1
Copy link
Member Author

@gaby Is there an exported version of that function? I copied it because it's unexported.

@gaby
Copy link
Member

gaby commented Oct 22, 2023

@gaby Is there an exported version of that function? I copied it because it's unexported.

Doesnt seem like it. Have we check how much performance difference there is between utils.GetMime and using native Go (this func https://github.com/golang/go/blob/master/src/net/textproto/reader.go#L632 ) ?

@nickajacks1
Copy link
Member Author

Have we check how much performance difference there is between utils.GetMime and using native Go

You're probably thinking about mime.TypeByExtension. There's already a benchmark comparing the two in utils/http_test.go. The TypeByExtension is twice as slow. In general, the mime package takes care of a lot of what we'd need for MIME and parameter parsing, but it's slow and allocates memory.

@sixcolors
Copy link
Member

sixcolors commented Oct 22, 2023

The benchmarks seem to be improving 😁

@nickajacks1 please check failing CI tests.

Attempts to approach the level of support offered by express,
but behavior may differ in unusual corner cases.
Some key behaviors from Express that are implemented:
 - If an offer does not have every parameter listed in the given Accept,
   it is rejected.
 - Parameters do not affect specificity.
 - In a given specificity, more parameters gives greater precedence
 - Parameters are unordered
 - Matching is case-insensitive
 - Surrounding quotes for parameter values are stripped
 - If an Accept type specifies a parameter more than once, the last
   value provided is taken.
 - Parameters after q are not processed.

https://www.rfc-editor.org/rfc/rfc9110#name-parameters
@nickajacks1
Copy link
Member Author

I wasn't sure what to do about this:

ST1003: should not use underscores in Go names; func Fuzz_Utils_GetOffer should be FuzzUtilsGetOffer (stylecheck)

This doesn't seem to be triggered for the other Benchmark_* and Test_* methods...?

@gaby did you want me to do something about validHeaderFieldByte?

@nickajacks1 nickajacks1 marked this pull request as ready for review October 22, 2023 22:42
@gaby
Copy link
Member

gaby commented Oct 22, 2023

I wasn't sure what to do about this:

ST1003: should not use underscores in Go names; func Fuzz_Utils_GetOffer should be FuzzUtilsGetOffer (stylecheck)

This doesn't seem to be triggered for the other Benchmark_* and Test_* methods...?

@gaby did you want me to do something about validHeaderFieldByte?

In the comment add URL that points to the original source code. It's the one i posted above

@sixcolors
Copy link
Member

I wasn't sure what to do about this:

ST1003: should not use underscores in Go names; func Fuzz_Utils_GetOffer should be FuzzUtilsGetOffer (stylecheck)

This doesn't seem to be triggered for the other Benchmark_* and Test_* methods...?

@gaby did you want me to do something about validHeaderFieldByte?

I tend to agree with the linter, Tests should be TestWhatever, BenchmarkWhatever and FuzzWhatever.

Copy link
Member

@sixcolors sixcolors left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nickajacks1 I'm seeing about 10% slowdown in Benchmark_Utils_GetOffer, awesome work!

Made a few testing related suggestions, otherwise LGTM!

helpers_fuzz_test.go Outdated Show resolved Hide resolved
helpers.go Show resolved Hide resolved
helpers.go Show resolved Hide resolved
helpers.go Show resolved Hide resolved
sixcolors

This comment was marked as duplicate.

@nickajacks1
Copy link
Member Author

Thanks, I'll implement the suggested changes and improve coverage this weekend.

@sixcolors
Copy link
Member

@nickajacks1 can you complete (or remove non applicable) checklist items from the PR description?

@nickajacks1
Copy link
Member Author

@nickajacks1 can you complete (or remove non applicable) checklist items from the PR description?

Done. Also added details of some quirks that were not implemented in this PR.

@sixcolors
Copy link
Member

@ReneWerner87 @gaby @efectn PR LGTM. I approved before.

@ReneWerner87
Copy link
Member

Ok will look tomorrow

@ReneWerner87
Copy link
Member

@nickajacks1 can you please share benchmarks again showing the master compared to the current state of the existing functionalities

@nickajacks1
Copy link
Member Author

Bench Accepts

master
goos: linux
goarch: amd64
pkg: github.com/gofiber/fiber/v2
cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 8839486	       135.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 8853195	       139.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7805179	       135.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 8777102	       140.6 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 8532048	       135.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 8545423	       136.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 8990457	       134.5 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 8810748	       135.9 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 8968890	       136.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 8821316	       135.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 8952948	       136.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 8813887	       135.9 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 8967898	       135.2 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 8391528	       134.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 8741970	       143.2 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 6189565	       188.6 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 6358563	       190.5 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 6245946	       196.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 6351415	       186.3 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 6215264	       187.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 6279278	       186.6 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 6415616	       189.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 6171139	       198.6 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 6187696	       192.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 6549969	       196.3 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 6304629	       186.6 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 6336711	       189.2 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 6361267	       192.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 6310435	       183.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 6247321	       194.6 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 8753716	       139.9 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 8693688	       140.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 8493938	       141.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 8311784	       146.2 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 8706558	       147.6 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 8805723	       141.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 8746408	       138.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 8558030	       140.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 8614651	       146.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 8621936	       146.6 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 8708131	       142.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 8589172	       144.3 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 8213953	       146.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 8415702	       146.2 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 8660049	       147.3 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	16403662	        71.86 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	16912604	        72.46 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	16084365	        70.73 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	16696166	        69.75 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	16815865	        71.65 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	17089466	        73.08 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	15634952	        70.18 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	16885665	        72.69 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	16786174	        73.04 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	16277292	        69.21 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	16778400	        69.51 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	17192934	        74.30 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	16519195	        69.91 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	17105088	        70.72 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	16805516	        69.26 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	11841327	       101.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	11701485	       109.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	11197510	       100.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	11380326	       105.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	11736454	       104.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	11458483	       102.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	11492564	       104.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	11742571	       106.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	11194947	       109.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	11642266	       100.3 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	11775794	       105.2 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	11217306	       107.9 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	11892580	       105.5 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	11464521	       109.9 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	11852080	       106.5 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7691950	       162.9 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7349106	       157.9 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7186768	       160.9 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7588566	       153.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7647355	       155.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7767267	       153.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7678732	       153.5 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7717558	       158.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7680273	       164.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7745534	       153.3 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7738284	       154.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7577661	       152.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7616619	       154.3 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7461470	       154.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7244853	       157.1 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/gofiber/fiber/v2	120.871s
PR
goos: linux
goarch: amd64
pkg: github.com/gofiber/fiber/v2
cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7096329	       164.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7097638	       165.3 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7407602	       166.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7600789	       167.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7393784	       165.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7291954	       166.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7315314	       164.6 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7331866	       164.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7442922	       166.2 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7344050	       164.9 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7211116	       171.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7264797	       165.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7486377	       168.6 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7171075	       163.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{".xml"}-8         	 7379565	       161.5 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 5563500	       223.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 4985742	       223.5 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 5433070	       216.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 5434917	       220.5 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 5531926	       225.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 5486791	       222.3 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 5542166	       224.6 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 5271254	       223.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 5591925	       216.3 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 5265901	       226.3 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 5612340	       215.5 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 5348716	       227.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 5654978	       215.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 5468170	       220.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"json",_"xml"}-8  	 5377267	       222.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 7216270	       171.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 6906916	       177.6 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 7100244	       176.9 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 7158033	       169.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 7086818	       178.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 7141851	       173.9 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 7254651	       170.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 7252482	       167.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 7055845	       177.2 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 6908438	       170.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 7294700	       169.2 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 6929644	       164.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 7097929	       178.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 7053505	       176.6 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8         	 6907918	       170.5 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	15529420	        76.33 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	14623612	        76.62 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	15061809	        76.99 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	15591081	        77.88 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	15324036	        80.08 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	15234596	        78.21 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	15766075	        76.14 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	15616936	        77.10 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	15574453	        79.75 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	15453198	        78.42 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	15398904	        80.08 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	14771750	        81.18 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	15434046	        77.04 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	15317492	        76.77 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsCharsets-8                                                     	15430281	        76.51 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	10074531	       115.9 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	10618377	       116.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	10838701	       116.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	10262442	       115.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	10652821	       114.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	10280632	       115.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	10522599	       116.3 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	10468162	       116.3 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	10479528	       117.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	10624704	       120.5 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	10271281	       111.2 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	10569188	       121.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	10471824	       115.5 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	10612772	       114.4 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsEncodings-8                                                    	10099026	       116.5 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 6755023	       173.9 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 6938752	       181.9 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7182954	       209.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 6714891	       169.3 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 6847004	       168.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 6891631	       174.0 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 6946251	       175.1 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7188087	       178.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 6989966	       178.8 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 6920467	       173.2 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 6907114	       179.6 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7051752	       174.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 6906237	       173.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 6981696	       172.7 ns/op	       0 B/op	       0 allocs/op
Benchmark_Ctx_AcceptsLanguages-8                                                    	 7066304	       178.5 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/gofiber/fiber/v2	123.728s
                                                                   │ master.txt  │               pr.txt                │
                                                                   │   sec/op    │   sec/op     vs base                │
_Ctx_Accepts/run-[]string{".xml"}-8                                  135.9n ± 1%   165.4n ± 1%  +21.71% (p=0.000 n=15)
_Ctx_Accepts/run-[]string{"json",_"xml"}-8                           189.7n ± 3%   222.8n ± 3%  +17.45% (p=0.000 n=15)
_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8   144.3n ± 2%   171.8n ± 3%  +19.06% (p=0.000 n=15)
_Ctx_AcceptsCharsets-8                                               70.73n ± 3%   77.10n ± 3%   +9.01% (p=0.000 n=15)
_Ctx_AcceptsEncodings-8                                              105.2n ± 3%   116.3n ± 1%  +10.55% (p=0.000 n=15)
_Ctx_AcceptsLanguages-8                                              154.4n ± 3%   174.7n ± 2%  +13.15% (p=0.000 n=15)
geomean                                                              127.4n        146.6n       +15.06%

Bench getOffer

master
goos: linux
goarch: amd64
pkg: github.com/gofiber/fiber/v2
cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
Benchmark_Utils_GetOffer-8   	 2465098	       472.0 ns/op
Benchmark_Utils_GetOffer-8   	 2553962	       474.5 ns/op
Benchmark_Utils_GetOffer-8   	 2556066	       473.3 ns/op
Benchmark_Utils_GetOffer-8   	 2522150	       467.9 ns/op
Benchmark_Utils_GetOffer-8   	 2552294	       468.4 ns/op
Benchmark_Utils_GetOffer-8   	 2526766	       469.2 ns/op
Benchmark_Utils_GetOffer-8   	 2550877	       471.2 ns/op
Benchmark_Utils_GetOffer-8   	 2567218	       480.6 ns/op
Benchmark_Utils_GetOffer-8   	 2513870	       477.6 ns/op
Benchmark_Utils_GetOffer-8   	 2513528	       481.9 ns/op
Benchmark_Utils_GetOffer-8   	 2491106	       469.3 ns/op
Benchmark_Utils_GetOffer-8   	 2617834	       470.0 ns/op
Benchmark_Utils_GetOffer-8   	 2535225	       474.3 ns/op
Benchmark_Utils_GetOffer-8   	 2447385	       481.4 ns/op
Benchmark_Utils_GetOffer-8   	 2471418	       484.8 ns/op
PASS
ok  	github.com/gofiber/fiber/v2	25.256s

PR
goos: linux
goarch: amd64
pkg: github.com/gofiber/fiber/v2
cpu: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
Benchmark_Utils_GetOffer-8              	 2235988	       534.5 ns/op
Benchmark_Utils_GetOffer-8              	 2280567	       535.2 ns/op
Benchmark_Utils_GetOffer-8              	 2257020	       525.3 ns/op
Benchmark_Utils_GetOffer-8              	 2269058	       528.2 ns/op
Benchmark_Utils_GetOffer-8              	 2249106	       528.2 ns/op
Benchmark_Utils_GetOffer-8              	 2287420	       541.7 ns/op
Benchmark_Utils_GetOffer-8              	 2297082	       545.3 ns/op
Benchmark_Utils_GetOffer-8              	 2272366	       531.2 ns/op
Benchmark_Utils_GetOffer-8              	 2266070	       532.3 ns/op
Benchmark_Utils_GetOffer-8              	 2166422	       527.4 ns/op
Benchmark_Utils_GetOffer-8              	 2266358	       527.5 ns/op
Benchmark_Utils_GetOffer-8              	 2298392	       548.0 ns/op
Benchmark_Utils_GetOffer-8              	 2279912	       554.1 ns/op
Benchmark_Utils_GetOffer-8              	 2265253	       540.6 ns/op
Benchmark_Utils_GetOffer-8              	 2256795	       551.3 ns/op
Benchmark_Utils_GetOffer_WithParams-8   	 2071987	       588.7 ns/op
Benchmark_Utils_GetOffer_WithParams-8   	 1995025	       586.1 ns/op
Benchmark_Utils_GetOffer_WithParams-8   	 2072061	       604.1 ns/op
Benchmark_Utils_GetOffer_WithParams-8   	 2018637	       597.6 ns/op
Benchmark_Utils_GetOffer_WithParams-8   	 2038538	       616.6 ns/op
Benchmark_Utils_GetOffer_WithParams-8   	 2050167	       593.8 ns/op
Benchmark_Utils_GetOffer_WithParams-8   	 2012140	       619.5 ns/op
Benchmark_Utils_GetOffer_WithParams-8   	 1944344	       578.0 ns/op
Benchmark_Utils_GetOffer_WithParams-8   	 2036491	       616.0 ns/op
Benchmark_Utils_GetOffer_WithParams-8   	 2036420	       594.4 ns/op
Benchmark_Utils_GetOffer_WithParams-8   	 2037222	       594.0 ns/op
Benchmark_Utils_GetOffer_WithParams-8   	 2070692	       619.6 ns/op
Benchmark_Utils_GetOffer_WithParams-8   	 2053047	       592.2 ns/op
Benchmark_Utils_GetOffer_WithParams-8   	 2074158	       616.4 ns/op
Benchmark_Utils_GetOffer_WithParams-8   	 2067346	       578.9 ns/op
PASS
ok  	github.com/gofiber/fiber/v2	53.682s
                             │ master_offer.txt │            pr_offer.txt             │
                             │      sec/op      │   sec/op     vs base                │
_Utils_GetOffer-8                   473.3n ± 2%   534.5n ± 2%  +12.93% (p=0.000 n=15)
_Utils_GetOffer_WithParams-8                      594.4n ± 4%
geomean                             473.3n        563.7n       +12.93%

@ReneWerner87
Copy link
Member

Bench Accepts

master
PR

                                                                   │ master.txt  │               pr.txt                │
                                                                   │   sec/op    │   sec/op     vs base                │
_Ctx_Accepts/run-[]string{".xml"}-8                                  135.9n ± 1%   165.4n ± 1%  +21.71% (p=0.000 n=15)
_Ctx_Accepts/run-[]string{"json",_"xml"}-8                           189.7n ± 3%   222.8n ± 3%  +17.45% (p=0.000 n=15)
_Ctx_Accepts/run-[]string{"application/json",_"application/xml"}-8   144.3n ± 2%   171.8n ± 3%  +19.06% (p=0.000 n=15)
_Ctx_AcceptsCharsets-8                                               70.73n ± 3%   77.10n ± 3%   +9.01% (p=0.000 n=15)
_Ctx_AcceptsEncodings-8                                              105.2n ± 3%   116.3n ± 1%  +10.55% (p=0.000 n=15)
_Ctx_AcceptsLanguages-8                                              154.4n ± 3%   174.7n ± 2%  +13.15% (p=0.000 n=15)
geomean                                                              127.4n        146.6n       +15.06%

Bench getOffer

master
PR

                             │ master_offer.txt │            pr_offer.txt             │
                             │      sec/op      │   sec/op     vs base                │
_Utils_GetOffer-8                   473.3n ± 2%   534.5n ± 2%  +12.93% (p=0.000 n=15)
_Utils_GetOffer_WithParams-8                      594.4n ± 4%
geomean                             473.3n        563.7n       +12.93%

I'm okay with the speed, but is there a way to keep this loss even smaller so that there is no loss of performance for the old cases?

@nickajacks1
Copy link
Member Author

Sure, I'll take another look and let you know what I find.

@ReneWerner87
Copy link
Member

Or do we want to merge it and later when we see optimizations simply implement them with a follow up pull request?
What do you think @efectn @gaby ?

@gaby
Copy link
Member

gaby commented Nov 7, 2023

Or do we want to merge it and later when we see optimizations simply implement them with a follow up pull request? What do you think @efectn @gaby ?

I'd say yes

@ReneWerner87 ReneWerner87 merged commit cbcb1ae into gofiber:master Nov 7, 2023
20 checks passed
Copy link

welcome bot commented Nov 7, 2023

Congrats on merging your first pull request! 🎉 We here at Fiber are proud of you! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants