diff options
author | Martin Möhrmann <moehrmann@google.com> | 2018-04-26 18:30:11 +0200 |
---|---|---|
committer | Martin Möhrmann <moehrmann@google.com> | 2018-05-06 04:28:23 +0000 |
commit | a8a60ac2a7bec701de6b502889e1dc740761e183 (patch) | |
tree | c53e32a00f0fc81f45099b0eadca4cfd6846ee24 /test/append.go | |
parent | 87412a143051d63f4ce68900f4668b2a3fb5c4f2 (diff) | |
download | go-a8a60ac2a7bec701de6b502889e1dc740761e183.tar.gz go-a8a60ac2a7bec701de6b502889e1dc740761e183.zip |
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>
Diffstat (limited to 'test/append.go')
-rw-r--r-- | test/append.go | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/test/append.go b/test/append.go index 3f6251ee50..3d16063406 100644 --- a/test/append.go +++ b/test/append.go @@ -13,14 +13,12 @@ import ( "reflect" ) - func verify(name string, result, expected interface{}) { if !reflect.DeepEqual(result, expected) { panic(name) } } - func main() { for _, t := range tests { verify(t.name, t.result, t.expected) @@ -30,6 +28,10 @@ func main() { verifyType() } +var ( + zero int = 0 + one int = 1 +) var tests = []struct { name string @@ -49,7 +51,6 @@ var tests = []struct { {"bool i", append([]bool{true, false, true}, []bool{true}...), []bool{true, false, true, true}}, {"bool j", append([]bool{true, false, true}, []bool{true, true, true}...), []bool{true, false, true, true, true, true}}, - {"byte a", append([]byte{}), []byte{}}, {"byte b", append([]byte{}, 0), []byte{0}}, {"byte c", append([]byte{}, 0, 1, 2, 3), []byte{0, 1, 2, 3}}, @@ -84,7 +85,6 @@ var tests = []struct { {"int16 i", append([]int16{0, 1, 2}, []int16{3}...), []int16{0, 1, 2, 3}}, {"int16 j", append([]int16{0, 1, 2}, []int16{3, 4, 5}...), []int16{0, 1, 2, 3, 4, 5}}, - {"uint32 a", append([]uint32{}), []uint32{}}, {"uint32 b", append([]uint32{}, 0), []uint32{0}}, {"uint32 c", append([]uint32{}, 0, 1, 2, 3), []uint32{0, 1, 2, 3}}, @@ -99,7 +99,6 @@ var tests = []struct { {"uint32 i", append([]uint32{0, 1, 2}, []uint32{3}...), []uint32{0, 1, 2, 3}}, {"uint32 j", append([]uint32{0, 1, 2}, []uint32{3, 4, 5}...), []uint32{0, 1, 2, 3, 4, 5}}, - {"float64 a", append([]float64{}), []float64{}}, {"float64 b", append([]float64{}, 0), []float64{0}}, {"float64 c", append([]float64{}, 0, 1, 2, 3), []float64{0, 1, 2, 3}}, @@ -114,7 +113,6 @@ var tests = []struct { {"float64 i", append([]float64{0, 1, 2}, []float64{3}...), []float64{0, 1, 2, 3}}, {"float64 j", append([]float64{0, 1, 2}, []float64{3, 4, 5}...), []float64{0, 1, 2, 3, 4, 5}}, - {"complex128 a", append([]complex128{}), []complex128{}}, {"complex128 b", append([]complex128{}, 0), []complex128{0}}, {"complex128 c", append([]complex128{}, 0, 1, 2, 3), []complex128{0, 1, 2, 3}}, @@ -129,7 +127,6 @@ var tests = []struct { {"complex128 i", append([]complex128{0, 1, 2}, []complex128{3}...), []complex128{0, 1, 2, 3}}, {"complex128 j", append([]complex128{0, 1, 2}, []complex128{3, 4, 5}...), []complex128{0, 1, 2, 3, 4, 5}}, - {"string a", append([]string{}), []string{}}, {"string b", append([]string{}, "0"), []string{"0"}}, {"string c", append([]string{}, "0", "1", "2", "3"), []string{"0", "1", "2", "3"}}, @@ -143,8 +140,19 @@ var tests = []struct { {"string i", append([]string{"0", "1", "2"}, []string{"3"}...), []string{"0", "1", "2", "3"}}, {"string j", append([]string{"0", "1", "2"}, []string{"3", "4", "5"}...), []string{"0", "1", "2", "3", "4", "5"}}, -} + {"make a", append([]string{}, make([]string, 0)...), []string{}}, + {"make b", append([]string(nil), make([]string, 0)...), []string(nil)}, + + {"make c", append([]struct{}{}, make([]struct{}, 0)...), []struct{}{}}, + {"make d", append([]struct{}{}, make([]struct{}, 2)...), make([]struct{}, 2)}, + + {"make e", append([]int{0, 1}, make([]int, 0)...), []int{0, 1}}, + {"make f", append([]int{0, 1}, make([]int, 2)...), []int{0, 1, 0, 0}}, + + {"make g", append([]*int{&zero, &one}, make([]*int, 0)...), []*int{&zero, &one}}, + {"make h", append([]*int{&zero, &one}, make([]*int, 2)...), []*int{&zero, &one, nil, nil}}, +} func verifyStruct() { type T struct { @@ -185,7 +193,6 @@ func verifyStruct() { verify("struct m", append(s, e...), r) } - func verifyInterface() { type T interface{} type S []T |