mirror of
https://github.com/golang/go
synced 2024-11-23 00:30:07 -07:00
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 <iant@google.com> Reviewed-by: Bryan Mills <bcmills@google.com> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Ian Lance Taylor <iant@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Valentin Deleplace <deleplace@google.com>
This commit is contained in:
parent
74c296b69f
commit
3de5b4da26
@ -88,7 +88,11 @@ func Insert[S ~[]E, E any](s S, i int, v ...E) S {
|
||||
copy(s2[i:], v)
|
||||
return s2
|
||||
}
|
||||
s2 := make(S, tot)
|
||||
// Use append rather than make so that we bump the size of
|
||||
// the slice up to the next storage class.
|
||||
// This is what Grow does but we don't call Grow because
|
||||
// that might copy the values twice.
|
||||
s2 := append(S(nil), make(S, tot)...)
|
||||
copy(s2, s[:i])
|
||||
copy(s2[i:], v)
|
||||
copy(s2[i+len(v):], s[i:])
|
||||
|
@ -256,6 +256,20 @@ func TestInsert(t *testing.T) {
|
||||
t.Errorf("Insert(%v, %d, %v...) = %v, want %v", test.s, test.i, test.add, got, test.want)
|
||||
}
|
||||
}
|
||||
|
||||
if !testenv.OptimizationOff() && !race.Enabled {
|
||||
// Allocations should be amortized.
|
||||
const count = 50
|
||||
n := testing.AllocsPerRun(10, func() {
|
||||
s := []int{1, 2, 3}
|
||||
for i := 0; i < count; i++ {
|
||||
s = Insert(s, 0, 1)
|
||||
}
|
||||
})
|
||||
if n > count/2 {
|
||||
t.Errorf("too many allocations inserting %d elements: got %v, want less than %d", count, n, count/2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var deleteTests = []struct {
|
||||
|
Loading…
Reference in New Issue
Block a user