2021年1月22日 星期五

Go 中,各種複製 slice 的方法的效能比較

Go 中,與 slice 相關的原生 func 有 func copy(dst, src []Type) intfunc 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 比較快。

沒有留言:

張貼留言