-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
cmd/compile,unicode/utf8: utf8.EncodeRune has different performance from the equivalent string conversion #48684
Comments
At the very least, this may be a useful data point for #27400. |
Yep, this is in part #27400. When I sprinkle the benchmarks with package main
import (
"bytes"
"runtime"
"testing"
"unicode/utf8"
)
//go:noinline
func utf8EncodeRune(b []byte, r rune) int {
return utf8.EncodeRune(b[:], r)
}
//go:noinline
func stringEncodeRune(b []byte, r rune) int {
return copy(b[:], string(r))
}
func BenchmarkEncodeRune(b *testing.B) {
b.ReportAllocs()
const r = '💩'
for n := b.N; n > 0; n-- {
b := [utf8.UTFMax]byte{}
n := utf8EncodeRune(b[:], r)
runtime.KeepAlive(b)
runtime.KeepAlive(n)
}
}
func BenchmarkCopyConvertedRune(b *testing.B) {
b.ReportAllocs()
const r = '💩'
for n := b.N; n > 0; n-- {
b := [utf8.UTFMax]byte{}
n := stringEncodeRune(b[:], r)
runtime.KeepAlive(b)
runtime.KeepAlive(n)
}
}
|
I don't think this is a fair benchmark. Most of
|
That's fair — but is also a pretty strong argument that |
I'm sympathetic, but not sure what the fix might be. Sometimes you want to benchmark the fully-optimized code, including any dead code elimination. Generally any benchmark with "_ = " in it is ripe for dead code elimination that maybe wasn't intended. Certainly fixing #27400 would help. |
@randall77 For a few years I have been under the impression that I think we need a |
@cespare So I think I misspoke a bit here:
It does force its argument to be generated, in the sense that the value must be available at the |
In this case I suspect that the problem may be on the input side rather than the output side. The input |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
What did you expect to see?
utf8.EncodeRune
performance exactly equal to the code usingcopy
and astring
conversion, since they are (as far as I can tell) semantically equivalent (compare #3939).I wrote a fuzz test to demonstrate equivalence, and found no counterexamples after 5 minutes of fuzzing:
What did you see instead?
utf8.EncodeRune
takes something like 9x longer than thestring
-and-copy
equivalent:The text was updated successfully, but these errors were encountered: