Patrick Kelley 8fd444092b initial
2025-05-07 15:35:15 -04:00

140 lines
4.2 KiB
C++

#include <benchmark/benchmark.h>
#include <algorithm>
#include <chrono>
#include <cmath>
#include <random>
#include <vector>
#include "prometheus/family.h"
#include "prometheus/registry.h"
#include "prometheus/summary.h"
using prometheus::Summary;
static const auto ITERATIONS = 262144;
static Summary::Quantiles CreateLinearQuantiles(int count) {
static auto generator = [](double x) {
static auto exp = [](double x) {
static const double A = 2;
return 1 - std::exp(-A * x);
};
return exp(x) / exp(1);
};
auto quantiles = Summary::Quantiles{};
for (auto i = 0; i < count; ++i) {
quantiles.emplace_back(generator(double(i) / count), 0.01);
}
return quantiles;
}
static void BM_Summary_Observe(benchmark::State& state) {
using prometheus::BuildSummary;
using prometheus::Registry;
using prometheus::Summary;
const auto number_of_quantiles = state.range(0);
Registry registry;
auto& summary_family =
BuildSummary().Name("benchmark_summary").Help("").Register(registry);
auto quantiles = CreateLinearQuantiles(number_of_quantiles);
auto& summary = summary_family.Add({}, quantiles);
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> d(0, 100);
while (state.KeepRunning()) {
auto observation = d(gen);
auto start = std::chrono::high_resolution_clock::now();
summary.Observe(observation);
auto end = std::chrono::high_resolution_clock::now();
auto elapsed_seconds =
std::chrono::duration_cast<std::chrono::duration<double>>(end - start);
state.SetIterationTime(elapsed_seconds.count());
}
}
BENCHMARK(BM_Summary_Observe)->Range(0, 64)->Iterations(ITERATIONS);
static void BM_Summary_Collect(benchmark::State& state) {
using prometheus::BuildSummary;
using prometheus::Registry;
using prometheus::Summary;
const auto number_of_quantiles = state.range(0);
const auto number_of_entries = state.range(1);
Registry registry;
auto& summary_family =
BuildSummary().Name("benchmark_summary").Help("").Register(registry);
auto quantiles = CreateLinearQuantiles(number_of_quantiles);
auto& summary = summary_family.Add({}, quantiles);
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> d(0, 100);
for (auto i = 1; i <= number_of_entries; ++i) summary.Observe(d(gen));
while (state.KeepRunning()) {
benchmark::DoNotOptimize(summary.Collect());
}
}
BENCHMARK(BM_Summary_Collect)->RangePair(0, 64, 0, ITERATIONS);
static void BM_Summary_Observe_Common(benchmark::State& state) {
using prometheus::BuildSummary;
using prometheus::Registry;
using prometheus::Summary;
Registry registry;
auto& summary_family =
BuildSummary().Name("benchmark_summary").Help("").Register(registry);
auto& summary = summary_family.Add(
{}, Summary::Quantiles{
{0.5, 0.05}, {0.9, 0.01}, {0.95, 0.005}, {0.99, 0.001}});
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> d(0, 100);
while (state.KeepRunning()) {
auto observation = d(gen);
auto start = std::chrono::high_resolution_clock::now();
summary.Observe(observation);
auto end = std::chrono::high_resolution_clock::now();
auto elapsed_seconds =
std::chrono::duration_cast<std::chrono::duration<double>>(end - start);
state.SetIterationTime(elapsed_seconds.count());
}
}
BENCHMARK(BM_Summary_Observe_Common)->Iterations(ITERATIONS);
static void BM_Summary_Collect_Common(benchmark::State& state) {
using prometheus::BuildSummary;
using prometheus::Registry;
using prometheus::Summary;
const auto number_of_entries = state.range(0);
Registry registry;
auto& summary_family =
BuildSummary().Name("benchmark_summary").Help("").Register(registry);
auto& summary = summary_family.Add(
{}, Summary::Quantiles{
{0.5, 0.05}, {0.9, 0.01}, {0.95, 0.005}, {0.99, 0.001}});
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> d(0, 100);
for (auto i = 1; i <= number_of_entries; ++i) summary.Observe(d(gen));
while (state.KeepRunning()) {
benchmark::DoNotOptimize(summary.Collect());
}
}
BENCHMARK(BM_Summary_Collect_Common)->Range(0, ITERATIONS);