Go-性能分析之案例一

43次阅读

共计 1141 个字符,预计需要花费 3 分钟才能阅读完成。

思考

相信大家在实际的项目开发中会遇到这么一个事,有的程序员写的代码不仅 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

待续

正文完
 0