-
Notifications
You must be signed in to change notification settings - Fork 18k
encoding/base64: improve performance up to 20% total #36910
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
Conversation
This PR (HEAD: 3525c07) has been imported to Gerrit for code review. Please visit https://go-review.googlesource.com/c/go/+/217117 to see it. Tip: You can toggle comments from me using the |
Message from Ian Lance Taylor: Patch Set 1: Code-Review-2 Let's not start applying unsafe transformations to speed up this package. Let's instead think about how to improve the compiler so that these transformations are not required. Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
Message from Kirill Korotaev: Patch Set 1: Well, for the 5 past years I'm looking into golang people are struggling to make compiler smarter yet simplest cases like this still do not work. You can check the huge history of the string<->[]byte conversion topic in issue tracking. Why having faster std library by using unsafe is considered so bad? we can remove unsafe usages one by one as compiler improves. Moreover, these places will be an exact pieces telling us where compiler is not so good and worth improving. Other thoughts: Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
Message from Ian Lance Taylor: Patch Set 1:
Using unsafe in the standard library, outside of specialized areas like runtime, reflect, and syscall, is bad because it shows a deficiency in the language or the implementation. If we permit ourselves to use unsafe in ordinary packages like encoding/base64 then we are using a trick. We are telling other people "Go is a safe and fast language" while we use techniques that we don't expect other people to use. That's not a good way to approach language and library design. (We have admittedly given ourselves exceptions like strings.Builder, but we try hard to keep those to only the most important parts of the library.) By all means use your faster version of encoding/base64 yourself, and make it available to other people. I just don't think that the standard library is the place for code like this. Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
Message from Daniel Martí: Patch Set 1: If one needs base64 encoding or decoding that's super fast, at the cost of simplicity or security, they can already use third party libraries with unsafe or assembly. The standard library avoids those as much as possible, and I agree with Ian here. Yes, it will take a while for the compiler to get really good at these optimizations, and that's fine. Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
Message from Kirill Korotaev: Patch Set 1:
Ian, Daniel, are you ok if I remove unsafe usage and leave boundary checks optimisation only? Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
Message from Daniel Martí: Patch Set 1: Sure, I'd be fine with an optimization for the bounds checks. Just make sure to include benchmark numbers to prove that the performance improved; the code has been optimized multiple times in the past, so we can't just work on assumptions. You should use benchstat with multiple runs, like -count=10. Also see perflock if the variance is too high. Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed (or fixed any issues), please reply here with What to do if you already signed the CLAIndividual signers
Corporate signers
ℹ️ Googlers: Go here for more info. |
This PR (HEAD: 6102ed7) has been imported to Gerrit for code review. Please visit https://go-review.googlesource.com/c/go/+/217117 to see it. Tip: You can toggle comments from me using the |
CLAs look good, thanks! ℹ️ Googlers: Go here for more info. |
Unfortunately compiler is not capable to realise that boundary checks are not necessary on each src[si+N] access. Selection of sub-slice helps. benchmark old MB/s new MB/s speedup BenchmarkEncodeToString-8 598.08 595.89 1.00x BenchmarkDecodeString/2-8 96.32 98.97 1.03x BenchmarkDecodeString/4-8 174.19 180.41 1.04x BenchmarkDecodeString/8-8 215.03 225.91 1.05x BenchmarkDecodeString/64-8 496.53 548.24 1.10x BenchmarkDecodeString/8192-8 778.83 916.62 1.18x
Message from Gobot Gobot: Patch Set 2: Congratulations on opening your first change. Thank you for your contribution! Next steps: Most changes in the Go project go through a few rounds of revision. This can be During May-July and Nov-Jan the Go project is in a code freeze, during which Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
This PR (HEAD: 2c87abc) has been imported to Gerrit for code review. Please visit https://go-review.googlesource.com/c/go/+/217117 to see it. Tip: You can toggle comments from me using the |
Message from Kirill Korotaev: Patch Set 3: Ian, Daniel, Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
Message from Kirill Korotaev: Patch Set 3: Code-Review+1 Ian? Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
Message from Daniel Martí: Patch Set 3: The change seems fine, but please use benchstat to prove your results and include its output in your commit message. See #23471 and https://godoc.org/golang.org/x/perf/cmd/benchstat. Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
Message from Daniel Martí: Patch Set 3: Also, please don't approve your own change. Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
Message from Kirill Korotaev: Patch Set 4:
Daniel, added the same benchmark results to PR message as well. Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
Message from Ian Lance Taylor: Patch Set 4: Run-TryBot+1 -Code-Review Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
Message from Gobot Gobot: Patch Set 4: TryBots beginning. Status page: https://farmer.golang.org/try?commit=0ad445f0 Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
Message from Gobot Gobot: Patch Set 4: TryBot-Result+1 TryBots are happy. Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
Improve base64 encoding/decoding performance by suppressing compiler boundary checks on decode. name old speed new speed delta EncodeToString-8 570MB/s ± 1% 573MB/s ± 1% ~ (p=0.421 n=5+5) DecodeString/2-8 88.6MB/s ± 3% 91.6MB/s ± 2% +3.37% (p=0.016 n=5+5) DecodeString/4-8 162MB/s ± 1% 168MB/s ± 0% +4.12% (p=0.008 n=5+5) DecodeString/8-8 203MB/s ± 0% 214MB/s ± 0% +5.18% (p=0.008 n=5+5) DecodeString/64-8 471MB/s ± 1% 520MB/s ± 1% +10.50% (p=0.008 n=5+5) DecodeString/8192-8 757MB/s ± 0% 895MB/s ± 1% +18.29% (p=0.008 n=5+5) Change-Id: I135243c11aa4c974a4a4e95c5c2abb0635d52c8c GitHub-Last-Rev: 2c87abc GitHub-Pull-Request: #36910 Reviewed-on: https://go-review.googlesource.com/c/go/+/217117 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
Message from Ian Lance Taylor: Patch Set 4: Code-Review+2 Thanks, much nicer. Please don’t reply on this GitHub thread. Visit golang.org/cl/217117. |
This PR is being closed because golang.org/cl/217117 has been merged. |
Improve base64 encoding/decoding performance by
suppressing compiler boundary checks on decode.
name old speed new speed delta
EncodeToString-8 570MB/s ± 1% 573MB/s ± 1% ~ (p=0.421 n=5+5)
DecodeString/2-8 88.6MB/s ± 3% 91.6MB/s ± 2% +3.37% (p=0.016 n=5+5)
DecodeString/4-8 162MB/s ± 1% 168MB/s ± 0% +4.12% (p=0.008 n=5+5)
DecodeString/8-8 203MB/s ± 0% 214MB/s ± 0% +5.18% (p=0.008 n=5+5)
DecodeString/64-8 471MB/s ± 1% 520MB/s ± 1% +10.50% (p=0.008 n=5+5)
DecodeString/8192-8 757MB/s ± 0% 895MB/s ± 1% +18.29% (p=0.008 n=5+5)