Última atualização:2026-10-12
Testes de performance com Google Benchmark¶
C++那些事: comece seus testes de BenchMark¶
0.Introdução¶
Objetivo desta seção: completar um pequeno projeto de BenchMark!
No dia a dia de desenvolvimento, como testar o desempenho das suas interfaces? Como montar rapidamente um framework de testes de BenchMark em C++?
Esta seção abre, passo a passo (Step By Step), a primeira lição de introdução ao BenchMark.
1.Estrutura do projeto¶
Usaremos como exemplo a inserção em vector e list para explicar o projeto de BenchMark.
Desta vez o projeto é gerenciado com Bazel; se você ainda não sabe como configurar o ambiente relacionado, consulte os cursos em vídeo/documentação anteriores.
Crie uma estrutura de projeto:
O BenchMark usa o projeto open source do google: Como antes, quando você usava uma biblioteca de terceiros, precisava compilar o código-fonte, gerar a biblioteca so e depois vinculá-la — trabalhoso demais! Aqui, usando o bazel diretamente, basta adicionar o projeto git da dependência no WORKSPACE; por exemplo, aqui é usada a versão v1.7.1 do google benchmark.git_repository(
name = "google_benchmark",
remote = "https://github.com/google/benchmark.git",
tag = "v1.7.1",
)
cc_binary(
name = "vector_list",
srcs = ["vector_list.cc"],
deps = [
"@google_benchmark//:benchmark",
]
)
2.Parte da Demo¶
Escreva duas funções de inserção, bem simples; o framework é o mostrado abaixo, com alguns pontos que merecem explicação:
- state é a informação de estado em tempo de execução do benchmark
- por exemplo: controle de suspensão, controle dos parâmetros de entrada etc.
- state.range(0) obtém o parâmetro de índice 0
- DoNotOptimize indica não fazer otimização do compilador
// 测试 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) significa começar em 8, multiplicando por 8 a cada vez, até 8192; isso corresponde ao state.range(0) acima, e esse número é passado como parâmetro
- BENCHMARK_MAIN indica usar a função main do google benchmark; sabemos que todo executável tem um main, e a razão de esse arquivo poder ser executado é que essa macro, ao ser expandida, é a função main. Você entendeu?
// 定义基准测试
BENCHMARK(BM_vectorInsert)->Range(8, 8<<10);
BENCHMARK(BM_listInsert)->Range(8, 8<<10);
// 运行基准测试
BENCHMARK_MAIN();
3.Conclusão¶
Nesta seção, aprendemos passo a passo o google benchmark e o aplicamos ao nosso próprio projeto, no qual você pode fazer muitas coisas interessantes. O código-fonte desta seção foi colocado na planeta de conhecimento para todos estudarem; junte-se a nós para trocar experiências~
Tópicos relacionados¶
- Escrevendo C++ FnOnce à mão | C++那些事
- Pequeno projeto de gRPC em C++ | C++那些事
- Comunicação entre processos em C++ na prática | C++那些事
- Demo de serviço de URL curta em C++ | C++那些事
- C++17 e SQLite para medir o tamanho de diretórios | C++那些事
- Servidor HTTP com corrotinas do C++20 | C++那些事
- Serialização ZeroCopy com Protobuf | C++那些事
- Acelerando Python com pybind11 | C++那些事
- Projeto de calculadora em pilha em C++ | C++那些事