Skip to content

Commit 3de5b4d

Browse files
ianlancetaylorgopherbot
authored andcommitted
slices: amortize allocations in Insert
Fixes #54948 Change-Id: I467afb940b539b100dcce687b05914a9da7b9ed2 Reviewed-on: https://go-review.googlesource.com/c/go/+/484159 Run-TryBot: Ian Lance Taylor <[email protected]> Reviewed-by: Bryan Mills <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Valentin Deleplace <[email protected]>
1 parent 74c296b commit 3de5b4d

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

src/slices/slices.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,11 @@ func Insert[S ~[]E, E any](s S, i int, v ...E) S {
8888
copy(s2[i:], v)
8989
return s2
9090
}
91-
s2 := make(S, tot)
91+
// Use append rather than make so that we bump the size of
92+
// the slice up to the next storage class.
93+
// This is what Grow does but we don't call Grow because
94+
// that might copy the values twice.
95+
s2 := append(S(nil), make(S, tot)...)
9296
copy(s2, s[:i])
9397
copy(s2[i:], v)
9498
copy(s2[i+len(v):], s[i:])

src/slices/slices_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,20 @@ func TestInsert(t *testing.T) {
256256
t.Errorf("Insert(%v, %d, %v...) = %v, want %v", test.s, test.i, test.add, got, test.want)
257257
}
258258
}
259+
260+
if !testenv.OptimizationOff() && !race.Enabled {
261+
// Allocations should be amortized.
262+
const count = 50
263+
n := testing.AllocsPerRun(10, func() {
264+
s := []int{1, 2, 3}
265+
for i := 0; i < count; i++ {
266+
s = Insert(s, 0, 1)
267+
}
268+
})
269+
if n > count/2 {
270+
t.Errorf("too many allocations inserting %d elements: got %v, want less than %d", count, n, count/2)
271+
}
272+
}
259273
}
260274

261275
var deleteTests = []struct {

0 commit comments

Comments
 (0)