Перейти к содержанию

Последнее обновление:2026-10-12

Тестирование производительности Google Benchmark

«C++那些事»: начинаем ваше тестирование BenchMark

0. Вступление

Цель раздела: выполнить небольшой проект на BenchMark!

В повседневной разработке — как протестировать производительность своего интерфейса? Как быстро построить на C++ фреймворк для тестов BenchMark?

В этом разделе Step By Step пройдём первый урок введения в BenchMark.

1. Структура проекта

Мы разберём проект BenchMark на примере вставки в vector и list.

Этот проект управляется с помощью 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, способ использования — @имя, настроенное выше//:benchmark.

cc_binary(
    name = "vector_list",
    srcs = ["vector_list.cc"],
    deps = [
        "@google_benchmark//:benchmark",
    ]
)
После этого в cc-файле можно использовать:

#include <benchmark/benchmark.h>

2. Раздел Demo

Пишем две функции вставки — очень просто; каркас показан ниже, кое-что нужно пояснить:

  • state — это информация о состоянии выполнения benchmark
  • например: управление сном, управление входными параметрами и т.д.
  • state.range(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 означает использование main-функции google benchmark; мы знаем, что у каждого исполняемого файла есть main, а этот файл выполняется именно потому, что после раскрытия этот макрос и есть функция main. Поняли?
// 定义基准测试
BENCHMARK(BM_vectorInsert)->Range(8, 8<<10);
BENCHMARK(BM_listInsert)->Range(8, 8<<10);

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

3. Итоги

В этом разделе мы Step by Step изучили google benchmark и применили его в собственном проекте — здесь можно делать много интересного. Исходники раздела выложены в закрытом сообществе для изучения; присоединяйтесь и обсудим~

Похожие темы

Комментарии