aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorEgon Elbre <egonelbre@gmail.com>2023-05-09 11:29:51 +0300
committerGopher Robot <gobot@golang.org>2023-09-04 17:50:46 +0000
commitc56f463412428f8a4d06bf67da9059b389c8d526 (patch)
treeefbaa4d9f0a047ca58103b3e2f9cb4f4deb3ace4 /src/runtime
parent778f5fc0793e72aaf70f2331566f45cb858e57b6 (diff)
downloadgo-c56f463412428f8a4d06bf67da9059b389c8d526.tar.xz
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>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/slice.go15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/runtime/slice.go b/src/runtime/slice.go
index 228697a708..29e2fd5cbd 100644
--- a/src/runtime/slice.go
+++ b/src/runtime/slice.go
@@ -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 {