Go言語

【Go言語】Benchmark関数で性能測定してみる

Go言語では、testingパッケージに用意されているBenchmark関数を使って性能測定することができます。

参考

書き方・実行方法

ベンチマーク関数は「BenchmarkXxx」という名前で定義します。接頭語に「Benchmark」、その後に測定したい関数名が続くというルールです。

echoという関数のベンチマークを計測する場合には、次のようになります。

echo_test.goファイル

package main

import "testing"

func BenchmarkEcho(b *testing.B) {
	for i := 0; i < b.N; i++ {
		echo()
	}
}

for文に出てくる b.Nは実行回数です。自動で、Nの小さな値を使って測定を行い、その後安定した時間の計測ができるだけの十分な値を推定してくれます。

実行方法は、

  • パッケージ内の全てのベンチマークを計測したい場合、go test -bench=.
  • 特定の関数のベンチマークのみを計測したい場合、go test -bench=Xxx(例. go  test -bench=Echo)

実際にベンチマークを計測してみる

まずは、計測対象の関数を用意します。

文字列のスライスを受け取り、半角スペース区切りの1つの文字列にする関数を2パターン実装しています。forループを使うものと、strings.Joinを使うものです。

main.go

package main

import (
	"fmt"
	"os"
	"strings"
)

func main() {
	fmt.Println("loop echo")
	fmt.Println(loopEcho(os.Args[1:]))
	fmt.Println("join echo")
	fmt.Println(joinEcho(os.Args[1:]))
}

func joinEcho(args []string) string {
	return strings.Join(args, " ")
}

func loopEcho(args []string) string {
	s, sep := "", ""
	for _, arg := range args {
		s += sep + arg
		sep = " "
	}

	return s
}

これに対して、Benchmark関数を書いていきます。

main_test.go

package main

import "testing"

var args = []string{"echo", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"}

func BenchmarkLoopEcho(b *testing.B) {
	for i := 0; i < b.N; i++ {
		loopEcho(args)
	}
}

func BenchmarkJoinEcho(b *testing.B) {
	for i := 0; i < b.N; i++ {
		joinEcho(args)
	}
}

実行

go test -bench=. -benchmem で実行します。(-benchmemはメモリ割り当ての情報を追加するオプション)

go benchmark 結果

strings.Joinを使った方が処理時間、メモリ量、メモリ割り当ての回数全てにおいて高パフォーマンスであることがわかりました。

【おすすめ図書】プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)

-Go言語

© 2021 フリエン生活 Powered by AFFINGER5