mirror of
https://github.com/golang/go
synced 2024-11-18 21:24:44 -07:00
runtime: optimize growslice
This is tiny optimization for growslice, which is probably too small to measure easily. Move the for loop to avoid multiple checks inside the loop. Also, use >> 2 instead of /4, which generates fewer instructions. Change-Id: I9ab09bdccb56f98ab22073f23d9e102c252238c7 Reviewed-on: https://go-review.googlesource.com/c/go/+/493795 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Egon Elbre <egonelbre@gmail.com> Auto-Submit: Ian Lance Taylor <iant@golang.org> Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
parent
778f5fc079
commit
c56f463412
@ -186,14 +186,21 @@ func growslice(oldPtr unsafe.Pointer, newLen, oldCap, num int, et *_type) slice
|
||||
if oldCap < threshold {
|
||||
newcap = doublecap
|
||||
} else {
|
||||
// Check 0 < newcap to detect overflow
|
||||
// and prevent an infinite loop.
|
||||
for 0 < newcap && newcap < newLen {
|
||||
for {
|
||||
// Transition from growing 2x for small slices
|
||||
// to growing 1.25x for large slices. This formula
|
||||
// gives a smooth-ish transition between the two.
|
||||
newcap += (newcap + 3*threshold) / 4
|
||||
newcap += (newcap + 3*threshold) >> 2
|
||||
|
||||
// We need to check `newcap >= newLen` and whether `newcap` overflowed.
|
||||
// newLen is guaranteed to be larger than zero, hence
|
||||
// when newcap overflows then `uint(newcap) > uint(newLen)`.
|
||||
// This allows to check for both with the same comparison.
|
||||
if uint(newcap) >= uint(newLen) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Set newcap to the requested cap when
|
||||
// the newcap calculation overflowed.
|
||||
if newcap <= 0 {
|
||||
|
Loading…
Reference in New Issue
Block a user