導入
Goでアプリケーションを開発する際、パフォーマンス改善は欠かせないタスクです。しかし、ベンチマークを数回実行しただけで「速くなった」と判断していませんか?実は、CPUの負荷やOSのタスクスケジューリングによって、ベンチマーク結果には常に「ノイズ」が含まれています。本稿で紹介するbenchstatは、複数のベンチマーク結果を統計的に分析し、その改善が本当に有意なものかを判定するための強力なツールです。これを使うことで、勘や偶然に頼らない、科学的なパフォーマンス最適化が可能になります。
基礎知識
benchstatは、Go公式の拡張パッケージ(golang.org/x/perf/cmd/benchstat)として提供されているコマンドラインツールです。
マイクロベンチマークは実行環境の影響を受けやすく、同じコードでも実行のたびに結果がブレることがあります。benchstatは、複数の実行結果から平均値や標準偏差を算出し、「統計的に見て有意な差があるか(偶然ではないか)」を計算してくれます。これにより、最適化の結果が「本物」なのかを客観的に判断できます。
実装/解決策
具体的な手順は以下の通りです。
1. 修正前のコードでベンチマークを複数回実行し、結果をファイルに保存する(例: old.txt)。
2. 修正後のコードで同様にベンチマークを実行し、結果を保存する(例: new.txt)。
3. benchstatコマンドで2つのファイルを比較する。
実行コマンド例:
go test -bench=. -count=10 > old.txt
(コードを修正)
go test -bench=. -count=10 > new.txt
benchstat old.txt new.txt
サンプルプログラム
比較対象となる、非常にシンプルなベンチマークの例です。
// main_test.go
package main
import “testing”
// 比較したい処理を関数として定義
func Calculate() int {
sum := 0
for i := 0; i < 1000; i++ {
sum += i
}
return sum
}
// ベンチマーク関数
func BenchmarkCalculate(b testing.B) {
// 試行回数を稼ぐためにループを実行
for i := 0; i < b.N; i++ {
Calculate()
}
}
/
実行方法:
ターミナルで以下のコマンドを実行してください。
-count=10 を指定することで、統計的に信頼できる十分なサンプル数を確保します。
go test -bench=BenchmarkCalculate -count=10 > result.txt
/
応用・注意点
benchstatを活用する際の重要なポイントは以下の2点です。
1. -countフラグの重要性: 統計的な信頼性を得るためには、少なくとも10回程度の試行(-count=10)を推奨します。試行回数が少ないと、ノイズを正しく除去できません。
2. 環境の安定化: どんなにツールが優秀でも、ベンチマーク中に重いバックグラウンド処理(Dockerのビルドやブラウザの動画再生など)が動いていると、結果は安定しません。電源アダプタを接続し、他のアプリケーションを閉じた状態で測定する「クリーンな環境」の維持を心がけましょう。
これらの手法を取り入れることで、チームメンバーに対して「なぜこの修正が有効なのか」を、定量的かつ説得力のある根拠を持って説明できるようになります。ぜひ日々の開発に取り入れてみてください。

コメント