mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: speed up growslice by avoiding divisions 2
This is a follow-up of https://go-review.googlesource.com/#/c/20653/ Special case computation for slices with elements of byte size or pointer size. name old time/op new time/op delta GrowSliceBytes-4 86.2ns ± 3% 75.4ns ± 2% -12.50% (p=0.000 n=20+20) GrowSliceInts-4 161ns ± 3% 136ns ± 3% -15.59% (p=0.000 n=19+19) GrowSlicePtr-4 239ns ± 2% 233ns ± 2% -2.52% (p=0.000 n=20+20) GrowSliceStruct24Bytes-4 258ns ± 3% 256ns ± 3% ~ (p=0.134 n=20+20) Change-Id: Ice5fa648058fe9d7fa89dee97ca359966f671128 Reviewed-on: https://go-review.googlesource.com/21101 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
1664ff96f7
commit
6b0688f742
2 changed files with 42 additions and 14 deletions
|
|
@ -56,11 +56,6 @@ func growslice(t *slicetype, old slice, cap int) slice {
|
|||
return slice{unsafe.Pointer(&zerobase), old.len, cap}
|
||||
}
|
||||
|
||||
maxcap := _MaxMem / et.size
|
||||
if cap < old.cap || uintptr(cap) > maxcap {
|
||||
panic(errorString("growslice: cap out of range"))
|
||||
}
|
||||
|
||||
newcap := old.cap
|
||||
doublecap := newcap + newcap
|
||||
if cap > doublecap {
|
||||
|
|
@ -73,17 +68,30 @@ func growslice(t *slicetype, old slice, cap int) slice {
|
|||
newcap += newcap / 4
|
||||
}
|
||||
}
|
||||
if uintptr(newcap) > maxcap {
|
||||
panic(errorString("growslice: cap out of range"))
|
||||
}
|
||||
}
|
||||
|
||||
lenmem := uintptr(old.len) * et.size
|
||||
capmem := roundupsize(uintptr(newcap) * et.size)
|
||||
if et.size == 1 {
|
||||
var lenmem, capmem, maxcap uintptr
|
||||
const ptrSize = unsafe.Sizeof((*byte)(nil))
|
||||
switch et.size {
|
||||
case 1:
|
||||
lenmem = uintptr(old.len)
|
||||
capmem = roundupsize(uintptr(newcap))
|
||||
newcap = int(capmem)
|
||||
} else {
|
||||
maxcap = _MaxMem
|
||||
case ptrSize:
|
||||
lenmem = uintptr(old.len) * ptrSize
|
||||
capmem = roundupsize(uintptr(newcap) * ptrSize)
|
||||
newcap = int(capmem / ptrSize)
|
||||
maxcap = _MaxMem / ptrSize
|
||||
default:
|
||||
lenmem = uintptr(old.len) * et.size
|
||||
capmem = roundupsize(uintptr(newcap) * et.size)
|
||||
newcap = int(capmem / et.size)
|
||||
maxcap = _MaxMem / et.size
|
||||
}
|
||||
|
||||
if cap < old.cap || uintptr(newcap) > maxcap {
|
||||
panic(errorString("growslice: cap out of range"))
|
||||
}
|
||||
|
||||
var p unsafe.Pointer
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue