-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
chore: preallocate slices #1842
Conversation
Thanks! Did you use a tool to find these spots or something else? |
yeah, repro by running: |
if len(pi.Addrs) > 0 { | ||
addrs = make([][]byte, 0, len(pi.Addrs)) | ||
} | ||
addrs := make([][]byte, len(pi.Addrs)) |
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.
Let’s keep the old behaviour of having this be nil. In this case I don’t think this matters, but generally we can’t be sure if callers check this.
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 don't understand why you're replacing append
s with assignments to a specific index. append
is the nicer way to do this, please don't change that.
I don’t have a preference, but assignments are technically faster. That said, I don’t think this matters here. |
I'd expect it to compile to exactly the same code. I ran a benchmark, and the two perform exactly the same. If at all, appending is slightly faster, but probably not statistically significant.
const l = 128
func BenchmarkAppend(b *testing.B) {
a := make([]int, 0, l)
for i := 0; i < b.N; i++ {
a = a[:0]
for j := 0; j < l; j++ {
a = append(a, j)
}
}
}
func BenchmarkAssign(b *testing.B) {
a := make([]int, l)
for i := 0; i < b.N; i++ {
for j := 0; j < l; j++ {
a[j] = j
}
}
} The reason people tend to prefer |
I've always gotten better perf from assignment than appending. Same code on my machine:
But I do agree that it is safer to use |
Thank you! |
Let me preface this by saying this doesn't matter at all :)
I went into a rabbit hole here because this doesn't make sense to me. Append has to do more work than an assign (which should be a single instruction). So it should be slower. Sure enough if we load up the code in godbolt we see that the append has one more compare and mov than assign should have. I say should have because this benchmark actually is flawed since the compiler optimizes the assignment and makes it the same as the noop (you don't see a Also I'm impressed with how well the compiler optimized the append loop. It really keeps the hot path very small. If we run without compiler optimizations ( Results from my tests here: https://gist.github.com/MarcoPolo/18b39366c6f57270059d0ef03c29351b#file-results-md |
When we know the final size of a slice preallocate for it to save memory.
Assigning directly is slightly faster than using append.