継続的なベンチマークとは何ですか?
継続的ベンチマーキングとは、チームのメンバーが頻繁に自分たちの成果物をベンチマークするソフトウェア開発のプラクティスです。 通常、各人が少なくとも日次でベンチマークを行い、その結果として一日に複数回のベンチマークが実施されます。 各ベンチマークは自動化されたビルドによって検証され、パフォーマンスの低下を可能な限り早く検出します。 多くのチームは、このアプローチによってパフォーマンスの低下が大幅に減少し、 パフォーマンスの高いソフトウェアをより迅速に開発できるようになることを実感しています。
今や、ソフトウェア業界の誰もが継続的インテグレーション(CI)を認識しています。 根本的なレベルにおいて、CIとはソフトウェアの機能回帰が本番環境に到達する前に検出し防止することです。 同様に、継続的ベンチマーキング(CB)とは、ソフトウェアの_パフォーマンス_回帰が本番環境に到達する前に検出し防止することです。 コード変更ごとにユニットテストがCIで実行されるのと同じ理由で、 コード変更ごとにパフォーマンステストをCBで実行するべきです。 このアナロジーは非常に的確であり、実はこのセクションの最初の段落は、Martin Fowler氏による2006年の継続的インテグレーションへの紹介文のマッドリブ版にすぎません。
🐰 パフォーマンスのバグはバグです!
CIでのベンチマーキング
俗説:CIでベンチマークは実行できない
ほとんどのベンチマークハーネスは、レイテンシやスループットを測定するためにシステムの壁時計を使用します。 これは非常に有用です。なぜなら、壁時計こそが開発者として私たちが最も気にかける指標だからです。 しかし、汎用のCI環境は壁時計時間を測定する際にノイズが多く一貫性に欠けることがよくあります。 継続的ベンチマーキングを行う際、このばらつきは結果に望ましくないノイズを加えてしまいます。
これに対処するための選択肢がいくつかあります。
- ベアメタルランナー
- 相対的な継続的ベンチマーキング
- 壁時計時間の代わりに命令数を数えるベンチマークハーネスに切り替える
はるかに多くの場合において、ベアメタルランナーが最良の選択肢です。 Bencherは、変動が2%未満のベアメタルランナーを提供しています。 これを実行間で30%超の変動が発生し得るGitHub Actionsランナーと比較してみてください。 継続的ベンチマーキング環境のばらつき、ひいてはノイズを減らすことにより、より細かなパフォーマンス低下を検出できるようになります。
パフォーマンスは重要
俗説:100msのレイテンシには気付けない
人間は100msのレイテンシを知覚できない、という主張をよく耳にします。 この主張の根拠としてNielsen Groupの応答時間に関する記事がしばしば引用されます。
0.1秒は、ユーザーがシステムは瞬時に反応していると感じられる限界であり、結果を表示する以外に特別なフィードバックは必要ないことを意味します。
- Jakob Nielsen、1993年1月1日
しかし、これは単純に正しくありません。
タスクによっては、人はわずか2msのレイテンシまで知覚できます。
これを証明する簡単な方法は、Dan Luu氏の実験です。ターミナルを開いて sleep 0; echo "ping" を実行し、続いて sleep 0.1; echo "pong" を実行してみてください。違いに気付きましたよね‽
もう一つのよくある混同は、レイテンシの知覚と人間の反応時間との区別です。視覚的刺激に反応するにはおよそ200msかかるとはいえ、それは出来事そのものの知覚とは独立しています。例えるなら、電車に2時間乗ることになる(反応時間)としても、電車が2分遅れている(知覚されるレイテンシ)ことには気付けるのです。
パフォーマンスは重要です!パフォーマンスは機能です!
- 100msごとに高速化 → コンバージョン1%増(Mobify、年間+$380,000の収益)
- 50%高速化 → 売上12%増(AutoAnything)
- 20%高速化 → コンバージョン10%増(Furniture Village)
- 40%高速化 → サインアップ15%増(Pinterest)
- 850ms高速化 → コンバージョン7%増(COOK)
- 1秒遅くなるごとに → ユーザー10%減(BBC)
ムーアの法則の終焉とともに、並列化可能なワークロードは並列化する必要が生じます。 しかし、ほとんどのワークロードは直列で実行する必要があり、 単により多くの計算資源を問題に投入することは、もはや手に負えない高コストな解決策になりつつあります。
継続的ベンチマーキングは、この変化に直面しながら パフォーマンスの高い現代のソフトウェアを開発・維持するための重要な構成要素です。

継続的ベンチマーキングツール
Bencherを作成する前、私たちは次のことができるツールを探し求めていました。
- ローカルでもCIでも_全く同じ_ベアメタルハードウェア上でベンチマークを実行できること
- 複数の言語にまたがってベンチマークを追跡できること
- 各言語標準のベンチマークハーネスの出力をシームレスに取り込めること
- カスタムベンチマークハーネスの出力にも拡張可能であること
- オープンソースで、セルフホスト可能であること
- 複数のCIホストと連携できること
- ユーザー認証と認可を備えていること
残念ながら、これらすべての条件を満たすツールは存在しませんでした。 私たちがインスピレーションを得た既存のベンチマーキングツールの包括的な一覧については、先行事例をご覧ください。
CIの外側での継続的ベンチマーキング
CIはあくまで最終確認の場であり、 テストが行われる唯一の場所であるべきではありません。 Bencherは、ローカルでもCIでも_全く同じ_ベアメタルハードウェア上でベンチマークを実行できる、初の継続的ベンチマーキングツールです。 これにより、開発者やエージェントは、進行中のローカル作業をプロジェクトのパフォーマンス履歴の任意の時点と比較することができます。
ローカルハードウェアで実行する場合、Bencherのベアメタル機能はマルチタスクの継続を可能にします。 システム上の他の作業をすべて止めて、古いブランチをチェックアウトし、比較を実行する必要はありません。
クラウド環境で実行する場合、Bencherのベアメタル機能は結果を信頼できるものにします。 騒がしい隣人、スロットリング、実行中のホスト切り替えを心配する必要はありません。
ビッグテックにおける継続的ベンチマーキング
Bencherのようなツールは、Microsoft、Facebook(現Meta)、Apple、Amazon、Netflix、Googleをはじめとする 数え切れないほどの企業で内部的に開発されてきました。 業界の巨人として、彼らは開発中のパフォーマンス監視の重要性を理解しており、 そうした知見を継続的ベンチマーキングを通じて開発プロセスに組み込んでいます。 私たちは、ビッグテックの壁の内側にあった継続的ベンチマーキングをオープンソースコミュニティにもたらすためにBencherを構築しました。 ビッグテックの継続的ベンチマーキングに関連する記事へのリンクについては、先行事例をご覧ください。
Bencher: 連続ベンチマーキング
Bencherは、継続的ベンチマーキングツールのスイートです。 パフォーマンスの後退があなたのユーザーに影響を与えたことはありますか? Bencherなら、それが起こるのを防げた可能性があります。 Bencherは、パフォーマンスの低下が_マージされる_前に検出し、防止することを可能にします。
- 実行: _まったく同じ_ベアメタルランナーとお気に入りのベンチマーキングツールを使用して、ベンチマークをローカルまたはCIで実行します。
bencherCLIはベアメタル上でのベンチマークの実行をオーケストレーションし、その結果を保存します。 - 追跡: ベンチマークの結果を時間と共に追跡します。ソースブランチ、テストベッド、測定基準に基づいてBencherのWebコンソールを使用して結果を監視、クエリ、グラフ化します。
- キャッチ: _まったく同じ_ベアメタルハードウェアを使用して、ローカルまたはCIでパフォーマンスの後退をキャッチします。Bencherは最先端のカスタマイズ可能な分析を使用して、パフォーマンスの後退がマージされる前にそれを検出します。
機能の後退を防ぐためにユニットテストが実行されるのと同じ理由で、Bencherを使用してベンチマークを実行してパフォーマンスの後退を防ぐべきです。パフォーマンスのバグはバグです!
パフォーマンスの回帰を捉えるのを開始してください - Bencher Cloudを無料で試す。
継続的ベンチマーキング対ローカルベンチマーク比較
ローカルで結果を比較できるベンチマークハーネスはいくつか存在します。 ローカル比較は、パフォーマンスチューニングを素早く反復する上で非常に有用です。 しかし、継続的にパフォーマンス低下を捕捉するためにそれに頼るべきではありません。 ユニットテストをローカルで実行できることがCIの必要性を否定しないのと同じように、 ベンチマークをローカルで実行・比較できることは継続的ベンチマーキングの必要性を否定しません。
Bencherがローカルベンチマーク比較ツールにはできないことをいくつか提供しています。
- 異なるテストベッド間での同一ベンチマークの比較
- 言語やハーネスを跨いだベンチマークの比較
- ベンチマーク結果のコラボレーションと共有
- ノイズを最小化するための専用テストベッドでのベンチマーク実行
- コピペ地獄からの解放
継続的ベンチマーキング対アプリケーションパフォーマンス管理(APM)
アプリケーションパフォーマンス管理(APM)は、現代のソフトウェアサービスにとって不可欠なツールです。 しかし、APMは本番環境での使用を想定して設計されています。 パフォーマンスの低下が検出される頃には、すでに顧客に影響を及ぼしてしまっています。
ほとんどの欠陥は、それを未然に防ぐためにかかったはずのコストを上回る代償を伴います。 欠陥が発生すると、直接的な修正コストだけでなく、損なわれた信頼関係、失われたビジネス、失われた開発時間といった間接的なコストによっても高くつくのです。
— Kent Beck、『Extreme Programming Explained』
BencherがAPMツールにはできないことをいくつか提供しています。
- パフォーマンスの低下をマージ_される前に_捕捉
- コードレビューにパフォーマンスの変化と影響を含める
- 本番環境でのオーバーヘッドなし
- オンプレミスの導入にも有効
- 本番のソースコードへの変更不要
継続的ベンチマーキング対オブザーバビリティ
名前が何であれ、バラはバラである。 上記の継続的ベンチマーキング対アプリケーションパフォーマンス管理をご覧ください。
継続的ベンチマーキング対継続的インテグレーション(CI)
継続的ベンチマーキング(CB)は、継続的インテグレーション(CI)を補完するものです。 コード変更ごとにユニットテストがCIで実行されるのと同じ理由で、 コード変更ごとにパフォーマンステストをCBで実行するべきです。
ユニットテストや受け入れテストは標準的な開発プラクティスとして広く受け入れられているにもかかわらず、 その流れはパフォーマンステストの領域にまでは及んでいません。 現在の一般的なツールは、テスターを使い捨てコードの作成とクリック&スクリプト的な発想へと誘導しがちです。 パフォーマンステストを第一級の市民として扱うことで、より多くの機能をカバーする優れたテストを作成でき、 ひいてはパフォーマンステストの作成と実行のためのより良いツールが生まれ、 その結果として保守可能かつ自らテスト可能なテストスイートが構築されます。
継続的ベンチマーキング対継続的負荷テスト
継続的ベンチマーキングと継続的負荷テストの違いを理解するには、 ベンチマーキングと 負荷テストの違いを 理解する必要があります。
| テスト種類 | テスト範囲 | テストユーザー |
|---|---|---|
| ベンチマーキング | 関数 - サービス | 1 - 多数 |
| 負荷テスト | サービス | 多数 |
ベンチマーキングは、関数レベル(マイクロベンチマーク)からサービスレベル(マクロベンチマーク)まで、ソフトウェアのパフォーマンスをテストできます。 ベンチマークは、コードの特定の部分のパフォーマンスを隔離された形でテストするのに適しています。 負荷テストはサービスレベルでのみソフトウェアのパフォーマンスをテストし、複数の同時ユーザーをモックします。 負荷テストは、特定の負荷下におけるサービス全体のパフォーマンスをテストするのに適しています。
🍦 アイスクリーム屋のトラックのパフォーマンスを追跡したいとしましょう。 ベンチマーキングは、アイスクリームコーンをすくうのにどれくらい時間がかかるか(マイクロベンチマーク)を測るのにも、 一人のお客さんが注文し、アイスクリームを受け取り、支払いを済ませるまでの時間(マクロベンチマーク)を測るのにも使えます。 負荷テストは、暑い夏の日にそのアイスクリーム屋のトラックが100人のお客さんをどれだけうまくさばけるかを確認するのに使えます。