mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: optimize append(x, make([]T, y)...) slice extension
Changes the compiler to recognize the slice extension pattern append(x, make([]T, y)...) and replace it with growslice and an optional memclr to avoid an allocation for make([]T, y). Memclr is not called in case growslice already allocated a new cleared backing array when T contains pointers. amd64: name old time/op new time/op delta ExtendSlice/IntSlice 103ns ± 4% 57ns ± 4% -44.55% (p=0.000 n=18+18) ExtendSlice/PointerSlice 155ns ± 3% 77ns ± 3% -49.93% (p=0.000 n=20+20) ExtendSlice/NoGrow 50.2ns ± 3% 5.2ns ± 2% -89.67% (p=0.000 n=18+18) name old alloc/op new alloc/op delta ExtendSlice/IntSlice 64.0B ± 0% 32.0B ± 0% -50.00% (p=0.000 n=20+20) ExtendSlice/PointerSlice 64.0B ± 0% 32.0B ± 0% -50.00% (p=0.000 n=20+20) ExtendSlice/NoGrow 32.0B ± 0% 0.0B -100.00% (p=0.000 n=20+20) name old allocs/op new allocs/op delta ExtendSlice/IntSlice 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=20+20) ExtendSlice/PointerSlice 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=20+20) ExtendSlice/NoGrow 1.00 ± 0% 0.00 -100.00% (p=0.000 n=20+20) Fixes #21266 Change-Id: Idc3077665f63cbe89762b590c5967a864fd1c07f Reviewed-on: https://go-review.googlesource.com/109517 Run-TryBot: Martin Möhrmann <moehrmann@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
parent
87412a1430
commit
a8a60ac2a7
11 changed files with 295 additions and 26 deletions
|
|
@ -44,6 +44,14 @@ func maxSliceCap(elemsize uintptr) uintptr {
|
|||
return maxAlloc / elemsize
|
||||
}
|
||||
|
||||
func panicmakeslicelen() {
|
||||
panic(errorString("makeslice: len out of range"))
|
||||
}
|
||||
|
||||
func panicmakeslicecap() {
|
||||
panic(errorString("makeslice: cap out of range"))
|
||||
}
|
||||
|
||||
func makeslice(et *_type, len, cap int) slice {
|
||||
// NOTE: The len > maxElements check here is not strictly necessary,
|
||||
// but it produces a 'len out of range' error instead of a 'cap out of range' error
|
||||
|
|
@ -52,11 +60,11 @@ func makeslice(et *_type, len, cap int) slice {
|
|||
// See issue 4085.
|
||||
maxElements := maxSliceCap(et.size)
|
||||
if len < 0 || uintptr(len) > maxElements {
|
||||
panic(errorString("makeslice: len out of range"))
|
||||
panicmakeslicelen()
|
||||
}
|
||||
|
||||
if cap < len || uintptr(cap) > maxElements {
|
||||
panic(errorString("makeslice: cap out of range"))
|
||||
panicmakeslicecap()
|
||||
}
|
||||
|
||||
p := mallocgc(et.size*uintptr(cap), et, true)
|
||||
|
|
@ -66,12 +74,12 @@ func makeslice(et *_type, len, cap int) slice {
|
|||
func makeslice64(et *_type, len64, cap64 int64) slice {
|
||||
len := int(len64)
|
||||
if int64(len) != len64 {
|
||||
panic(errorString("makeslice: len out of range"))
|
||||
panicmakeslicelen()
|
||||
}
|
||||
|
||||
cap := int(cap64)
|
||||
if int64(cap) != cap64 {
|
||||
panic(errorString("makeslice: cap out of range"))
|
||||
panicmakeslicecap()
|
||||
}
|
||||
|
||||
return makeslice(et, len, cap)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue