Go 中,與 slice 相關的原生 func 有 func copy(dst, src []Type) int
、func append(slice []Type, elems ...Type) []Type
這兩個。
這兩者都能夠用來複製 slice (clone)。
那這樣的話效能呢?
package main
import (
"testing"
)
type Data struct {
}
type Info struct {
D1, D2 [][]Data
D3 []Data
}
func (i *Info) Clone1() Info {
result := Info{
make([][]Data, len(i.D1)),
make([][]Data, len(i.D2)),
make([]Data, len(i.D3)),
}
copy(result.D1, i.D1)
copy(result.D2, i.D2)
copy(result.D3, i.D3)
return result
}
func (i *Info) Clone2() Info {
return Info{
append([][]Data{}, i.D1...),
append([][]Data{}, i.D2...),
append([]Data{}, i.D3...),
}
}
func (i *Info) Clone3() Info {
return Info{
append(make([][]Data, 0), i.D1...),
append(make([][]Data, 0), i.D2...),
append(make([]Data, 0), i.D3...),
}
}
func BenchmarkClone1(b *testing.B) {
orig := Info{
D1: [][]Data{
[]Data{{}, {}, {}},
},
D2: [][]Data{
[]Data{{}, {}, {}},
[]Data{{}, {}},
},
D3: []Data{
{},
},
}
for i := 0; i < b.N; i++ {
orig.Clone1()
}
}
func BenchmarkClone2(b *testing.B) {
orig := Info{
D1: [][]Data{
[]Data{{}, {}, {}},
},
D2: [][]Data{
[]Data{{}, {}, {}},
[]Data{{}, {}},
},
D3: []Data{
{},
},
}
for i := 0; i < b.N; i++ {
orig.Clone2()
}
}
func BenchmarkClone3(b *testing.B) {
orig := Info{
D1: [][]Data{
[]Data{{}, {}, {}},
},
D2: [][]Data{
[]Data{{}, {}, {}},
[]Data{{}, {}},
},
D3: []Data{
{},
},
}
for i := 0; i < b.N; i++ {
orig.Clone3()
}
}
終端機輸入
go test -v -bench=. -run=none -benchmem .
會得到:
PASS goos: windows goarch: amd64 BenchmarkClone1 BenchmarkClone1-4 9458664 124 ns/op 80 B/op 2 allocs/op BenchmarkClone2 BenchmarkClone2-4 6964324 167 ns/op 80 B/op 2 allocs/op BenchmarkClone3 BenchmarkClone3-4 6954976 167 ns/op 80 B/op 2 allocs/op
由此可見,要複製一個 slice ,用 append 比 copy 好的多了。
至於方法 2 和 方法 3 效能上的差距,其實不大,甚至有時候我進行效能測試時,方法 2 比較快。
沒有留言:
張貼留言