const N = 20
+func BenchmarkGrowSliceBytes(b *testing.B) {
+ b.StopTimer()
+ var x = make([]byte, 8)
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ _ = append([]byte(nil), x...)
+ }
+}
+
+func BenchmarkGrowSliceInts(b *testing.B) {
+ b.StopTimer()
+ var x = make([]int, 8)
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ _ = append([]int(nil), x...)
+ }
+}
+
func BenchmarkAppend(b *testing.B) {
b.StopTimer()
x := make([]int, 0, N)
// and it returns a new slice with at least that capacity, with the old data
// copied into it.
func growslice(t *slicetype, old slice, cap int) slice {
- if cap < old.cap || t.elem.size > 0 && uintptr(cap) > _MaxMem/t.elem.size {
- panic(errorString("growslice: cap out of range"))
- }
-
if raceenabled {
callerpc := getcallerpc(unsafe.Pointer(&t))
racereadrangepc(old.array, uintptr(old.len*int(t.elem.size)), callerpc, funcPC(growslice))
et := t.elem
if et.size == 0 {
+ if cap < old.cap {
+ panic(errorString("growslice: cap out of range"))
+ }
// append should not create a slice with nil pointer but non-zero len.
// We assume that append doesn't need to preserve old.array in this case.
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
if newcap+newcap < cap {
newcap = cap
}
}
- if uintptr(newcap) >= _MaxMem/et.size {
+ if uintptr(newcap) >= maxcap {
panic(errorString("growslice: cap out of range"))
}
+
lenmem := uintptr(old.len) * et.size
capmem := roundupsize(uintptr(newcap) * et.size)
- newcap = int(capmem / et.size)
+ if et.size == 1 {
+ newcap = int(capmem)
+ } else {
+ newcap = int(capmem / et.size)
+ }
+
var p unsafe.Pointer
if et.kind&kindNoPointers != 0 {
p = rawmem(capmem)