思考
相信大家在实际的项目开发中会遇到这么一个事,有的程序员写的代码不仅bug少,而且性能高;而有的程序员写的代码能否流畅的跑起来,都是一个很大问题。
而我们今天要讨论的就是一个关于性能优化的案例分析。
案例分析
我们先来构造一些基础数据(长度为10亿的切片,并赋上值):
var testData = GenerateData()
// generate billion slice data
func GenerateData() []int {
data := make([]int, 1000000000)
for key, _ := range data {
data[key] = key % 128
}
return data
}
// get length
func GetDataLen() int {
return len(testData)
}
案例一
// case one
func CaseSumOne(result *int) {
data := GenerateData()
for i := 0; i < GetDataLen(); i++ {
*result += data[i]
}
}
// case two
func CaseSumTwo(result *int) {
data := GenerateData()
dataLen := GetDataLen()
for i := 0; i < dataLen; i++ {
*result += data[i]
}
}
执行结果
$ go test -bench=.
goos: windows
goarch: amd64
BenchmarkCaseSumOne-8 1 7439749000 ns/op
BenchmarkCaseSumTwo-8 1 2529266700 ns/op
PASS
ok _/C_/go-code/perform/case-one 14.059s
问题分析
- CaseSumTwo执行效率是CaseSumOne的2.94倍,快了近三倍,这是为什么呢?
- 其实很容易猜到,这里有一个连续的函数调用“GetDataLen()”,
案例二
// case three
func CaseSumThree(result *int) {
data := GenerateData()
dataLen := GetDataLen()
tmp := *result
for i:= 0; i < dataLen; i++ {
tmp += data[i]
}
*result = tmp
}
执行
$ go test -bench=.
goos: windows
goarch: amd64
BenchmarkCaseSumOne-8 1 7439749000 ns/op
BenchmarkCaseSumTwo-8 1 2529266700 ns/op
BenchmarkCaseSumThree-8 1 1657554600 ns/op
PASS
ok _/C_/go-code/perform/case-one 15.717s
发表回复