Go 語言不只有內建基本的 Testing 功能,另外也內建了 Benchmark 工具,讓開發者可以快速的驗證自己寫的程式碼效能如何?該如何使用基本的 Benchmark 工具,底下用簡單的例子來說明如何寫 Benchmark,透過內建工具可以知道程式碼單次執行多少時間,以及用了多少記憶體。不多說直接用『數字轉字串』來當例子。
線上影片
如果您不想看底下的文字說明,可以直接參考線上影片教學: 另外我在 Udemy 上面開了兩門課程,一門 drone 另一門 golang 教學,如果對這兩門課有興趣的話,都可以購買,目前都是特價 $1800- Go 語言實戰 $1800
- 一天學會 DEVOPS 自動化流程 $1800
- 富邦銀行: 012
- 富邦帳號: 746168268370
- 匯款金額: 台幣 $3000 元
如何寫 Benchmark
建立main_test.go
檔案
func BenchmarkPrintInt2String01(b *testing.B) { for i := 0; i < b.N; i++ { printInt2String01(100) } }
- 檔案名稱一定要用
_test.go
當結尾 - func 名稱開頭要用
Benchmark
- for 循環內要放置要測試的程式碼
- b.N 是 go 語言內建提供的循環,根據一秒鐘的時間計算
- 跟測試不同的是帶入
b *testing.B
參數
$ go test -v -bench=. -run=none . goos: darwin goarch: amd64 BenchmarkPrintInt2String01-4 10000000 140 ns/op PASS基本的 benchmark 測試也是透過
go test
指令,不同的是要加上 -bench=.
,這樣才會跑 benchmark 部分,否則預設只有跑測試程式,大家可以看到 -4
代表目前的 CPU 核心數,也就是 GOMAXPROCS
的值,另外 -run
可以用在跑特定的測試函示,但是假設沒有指定 -run
時,你會看到預設跑測試 + benchmark,所以這邊補上 -run=none
的用意是不要跑任何測試,只有跑 benchmark,最後看看輸出結果,其中 10000000
代表一秒鐘可以跑 1000 萬次,每一次需要 140 ns
,如果你想跑兩秒,請加上此參數在命令列 -benchtime=2s
,但是個人覺得沒什麼意義。
效能比較
底下直接看看『數字轉字串』效能評估,參考底下寫出三種數字轉字串函式,線上程式碼func printInt2String01(num int) string { return fmt.Sprintf("%d", num) } func printInt2String02(num int64) string { return strconv.FormatInt(num, 10) } func printInt2String03(num int) string { return strconv.Itoa(num) }接著寫 benchmark,線上程式碼
func BenchmarkPrintInt2String01(b *testing.B) { for i := 0; i < b.N; i++ { printInt2String01(100) } } func BenchmarkPrintInt2String02(b *testing.B) { for i := 0; i < b.N; i++ { printInt2String02(int64(100)) } } func BenchmarkPrintInt2String03(b *testing.B) { for i := 0; i < b.N; i++ { printInt2String03(100) } }跑測試
$ go test -v -bench=. -run=none -benchmem . goos: darwin goarch: amd64 BenchmarkPrintInt2String01-4 10000000 125 ns/op 16 B/op 2 allocs/op BenchmarkPrintInt2String02-4 30000000 37.8 ns/op 3 B/op 1 allocs/op BenchmarkPrintInt2String03-4 30000000 38.6 ns/op 3 B/op 1 allocs/op PASS ok _/Users/mtk10671/git/go/src/github.com/go-training/training/example20-write-benchmark 3.800s可以很清楚看到使用
strconv.FormatInt
效能是最好的。透過 -benchmem
可以清楚知道記憶體分配方式,用此方式就可以知道要優化哪些函示。1 allocs/op
代表每次執行都需要搭配一個記憶體空間,而一個記憶體空間為 3 Bytes
。