Golang ---基準測試

 

 

什麼是基準測試

基準測試,是一種測試代碼性能的方法,好比你有多種不一樣的方案,均可以解決問題,那麼究竟是那種方案性能更好呢?這時候基準測試就派上用場了。框架

基準測試主要是經過測試CPU和內存的效率問題,來評估被測試代碼的性能,進而找到更好的解決方案。好比連接池的數量不是越多越好,那麼哪一個值纔是最優值呢,這就須要配合基準測試不斷調優了。函數

 

如何編寫基準測試

基準測試代碼的編寫和單元測試很是類似,它也有必定的規則,咱們先看一個示例。性能

itoa_test.go單元測試

package gotest

import (
	"fmt"
	"testing"
)

//itoa_test.go
func BenchmarkSprintf(b *testing.B) {
	num := 10
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		fmt.Sprintf("%d", num)
	}
}

  

這是一個基準測試的例子,從中咱們能夠看出如下規則:測試

  • 基準測試的代碼文件必須以_test.go結尾
  • 基準測試的函數必須以Benchmark開頭,必須是可導出的
  • 基準測試函數必須接受一個指向Benchmark類型的指針做爲惟一參數
  • 基準測試函數不能有返回值
    b.ResetTimer是重置計時器,這樣能夠避免for循環以前的初始化代碼的干擾
    最後的for循環很重要,被測試的代碼要放到循環裏
    b.N是基準測試框架提供的,表示循環的次數,由於須要反覆調用測試的代碼,才能夠評估性能
    下面咱們運行下基準測試,看看效果。

 

運行基準測試也要使用go test命令,不過咱們要加上-bench=標記,它接受一個表達式做爲參數,匹配基準測試的函數,.表示運行全部基準測試。優化

由於默認狀況下go test 會運行單元測試,爲了防止單元測試的輸出影響咱們查看基準測試的結果,可使用-run=匹配一個歷來沒有的單元測試方法,過濾掉單元測試的輸出,咱們這裏使用none,由於咱們基本上不會建立這個名字的單元測試方法。spa

下面着重解釋下說出的結果,看到函數後面的-2了嗎?這個表示運行時對應的GOMAXPROCS的值。接着的5000000表示運行for循環的次數,也就是調用被測試代碼的次數,最後的290 ns/op表示每次須要話費290納秒。指針

以上是測試時間默認是1秒,也就是1秒的時間,調用5000000次,每次調用花費290納秒。若是想讓測試運行的時間更長,能夠經過-benchtime指定,好比3秒。code

能夠發現,咱們加長了測試時間,測試的次數變多了,可是最終的性能結果:每次執行的時間,並無太大變化。通常來講這個值最好不要超過3秒,意義不大。orm

性能對比

上面那個基準測試的例子,實際上是一個int類型轉爲string類型的例子,標準庫裏還有幾種方法,咱們看下哪一種性能更加。



package gotest

import (
	"fmt"
	"strconv"
	"testing"
)

func BenchmarkSprintf(b *testing.B) {
	num := 10
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		fmt.Sprintf("%d", num)
	}
}

func BenchmarkFormat(b *testing.B) {
	num := int64(10)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		strconv.FormatInt(num, 10)
	}
}

func BenchmarkItoa(b *testing.B) {
	num := 10
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		strconv.Itoa(num)
	}
}

  運行基準測試,看看結果

 

 從結果上看strconv.FormatInt函數是最快的,其次是strconv.Itoa,而後是fmt.Sprintf最慢,前兩個函數性能達到了最後一個的10倍多。那麼最後一個爲何這麼慢的,咱們再經過-benchmem找到根本緣由。

 

-benchmem能夠提供每次操做分配內存的次數,以及每次操做分配的字節數。allocs/op 表示每次操做從堆上分配內存的次數。B/op 表示每次操做分配的字節數。 從結果咱們能夠看到,性能高的兩個函數,每次操做都是進行0次內存分配,而最慢的那個要分配2次;性能高的每次操做分配8個字節內存,而慢的那個函數每次須要分配0字節的內存。從這個數據咱們就知道它爲何這麼慢了,內存分配都佔用都過高。
在代碼開發中,對於咱們要求性能的地方,編寫基準測試很是重要,這有助於咱們開發出性能更好的代碼。不過性能、可用性、複用性等也要有一個相對的取捨,不能爲了追求性能而過分優化。
相關文章
相關標籤/搜索