由于append在编译期会转换成汇编代码,所以append本身几乎没有效率上的开销。真正影响效率的是切片的容量,如果能够预先知道拷贝所需要的容量大小,则在初始化切片时一定要指定容量大小,避免在拷贝过程中切片内部生成新的数组。从下面的测试可以看出效率的对比:
main.go
package main
import (
"fmt"
)
func Add1(sl []string) []string {
n := make([]string, 0)
n = append(n, "begin")
n = append(n, sl...)
n = append(n, "end")
return n
}
func Add2(sl []string) []string {
n := make([]string, 0, len(sl)+2)
n = append(n, "begin")
n = append(n, sl...)
n = append(n, "end")
return n
}
func Add3(sl []string) []string {
n := make([]string, len(sl)+2)
n[0] = "begin"
var i int
for ; i < len(sl); i++ {
n[i+1] = sl[i]
}
n[i+1] = "end"
return n
}
func main() {
test := []string{"item1", "item2", "item3", "item4"}
fmt.Printf("%v\n", test)
fmt.Printf("%v\n", Add1(test))
fmt.Printf("%v\n", Add2(test))
fmt.Printf("%v\n", Add3(test))
}
main_test.go
package main
import (
"testing"
)
var sl = []string{"item1", "item2", "item3", "item4"}
func BenchmarkAdd1(b *testing.B) {
for i := 0; i < b.N; i++ {
Add1(sl)
}
}
func BenchmarkAdd2(b *testing.B) {
for i := 0; i < b.N; i++ {
Add2(sl)
}
}
func BenchmarkAdd3(b *testing.B) {
for i := 0; i < b.N; i++ {
Add3(sl)
}
}
go test -bench=.
goos: linux
goarch: amd64
pkg: append
BenchmarkAdd1-4 738122 1420 ns/op
BenchmarkAdd2-4 2516319 477 ns/op
BenchmarkAdd3-4 2421643 488 ns/op
PASS
ok append 4.539s
相关文章:
《Go语言:几种深度拷贝(deepcopy)方法的性能对比》
《Go语言:append函数源码学习及切片深度拷贝问题》