コンテンツにスキップ

最終更新:2026-10-12

Google Benchmark 性能テスト

『C++那些事』の BenchMark テストを始めよう

0.はじめに

この節の目標:BenchMark ミニプロジェクトを完成させること!

日頃の開発の中で、自分のインターフェースの性能をどのようにテストしていますか?C++ では BenchMark テストフレームワークをどう素早く構築すればよいでしょうか?

この節では Step By Step で BenchMark 入門の第一歩を踏み出します。

1.プロジェクト構造

vector と list への挿入を例に、BenchMark プロジェクトを解説します。

今回のプロジェクトは Bazel で管理しています。関連環境の設定方法がまだ分からない方は、以前の動画講座・ドキュメント資料を参照してください。

プロジェクト構造を次のように作成します:


BenchMark には google のオープンソースプロジェクトを採用しています:

https://github.com/google/benchmark.git

従来はサードパーティライブラリを使う際、自分でソースからコンパイルして so ライブラリを生成し、リンクする必要があり、非常に面倒でした!ここでは bazel で管理するので、WORKSPACE に依存する git プロジェクトを追加するだけです。例えばここでは google benchmark の v1.7.1 を採用しています。

git_repository(
    name = "google_benchmark",
    remote = "https://github.com/google/benchmark.git",
    tag = "v1.7.1",
)

続いてメインロジックを実装します。src ディレクトリを作成し、その中に BUILD ファイルを追加します。目的は cpp ファイルをコンパイルすることです。注意:ここでは benchmark ライブラリに依存しており、使用方法は @前に設定した name//:benchmark です。

cc_binary(
    name = "vector_list",
    srcs = ["vector_list.cc"],
    deps = [
        "@google_benchmark//:benchmark",
    ]
)

こうすることで、cc ファイルの中で使用できます:

#include <benchmark/benchmark.h>

2.Demoのセクション

2 つの挿入関数を書きます。非常にシンプルで、フレームワークは次のとおりです。説明が必要な点は以下のとおりです:

  • state は benchmark の実行時状態情報です
  • 例:スリープ制御、入力パラメータの制御など
  • state.range(0) は第 0 パラメータの取得です
  • DoNotOptimize はコンパイラ最適化を行わないことを示します
// 测试 std::vector 的插入速度
static void BM_vectorInsert(benchmark::State& state) {
    for (auto _ : state) {
        std::vector<int> v;
        for (size_t i = 0; i < state.range(0); ++i) {
            v.insert(v.begin() + i, i);
        }
        benchmark::DoNotOptimize(v);
    }
}

// 测试 std::list 的插入速度
static void BM_listInsert(benchmark::State& state) {
    for (auto _ : state) {
        std::list<int> l;
        for (size_t i = 0; i < state.range(0); ++i) {
            l.insert(l.begin(), i);
        }
        benchmark::DoNotOptimize(l);
    }
}

メインエントリからの呼び出し:

  • Range(8, 8 << 10) は 8 から始めて毎回 8 倍し、8192 に達するまでを表します。これは上の state.range(0) に対応し、この数値が引数として渡されます
  • BENCHMARK_MAIN は google benchmark の main 関数を使用することを意味します。すべての実行ファイルには main があることは周知のとおり、このファイルが実行できる理由は、このマクロが展開されると main 関数になるからです。お分かりいただけましたか?
// 定义基准测试
BENCHMARK(BM_vectorInsert)->Range(8, 8<<10);
BENCHMARK(BM_listInsert)->Range(8, 8<<10);

// 运行基准测试
BENCHMARK_MAIN();

3.まとめ

この節では Step by Step で google benchmark を学び、それを自分のプロジェクトに適用しました。ここではいろいろと面白いことができます。この節のソースコードは知識星球に置いてあり、学習用にご利用ください。ぜひ参加して一緒に交流しましょう~

関連トピック

コメント