MicroLogger/bench/main.cc
2025-06-19 08:44:34 +00:00

194 lines
4.8 KiB
C++

#include <cmath>
#include <functional>
#include "benchmark/benchmark.h"
#include "logger.hh"
//! AI generated
static double taylor_approximation(
double x, // Point to evaluate
double a, // Expansion point
int n, // Number of terms
const std::function<double(double)>& func, // f(a)
const std::function<double(int, double)>& derivative // f^(k)(a)
) {
double result = 0.0;
double power = 1.0; // (x - a)^0
double factorial = 1.0; // 0!
// Zeroth derivative term (k=0)
result += func(a) * power / factorial;
// Subsequent terms (k=1 to n-1)
for (int k = 1; k < n; k++) {
factorial *= k; // k!
power *= (x - a); // (x - a)^k
double deriv = derivative(k, a);
result += deriv * power / factorial;
}
return result;
}
static double calc_exp_taylor() {
auto exp_deriv = [](int k, double a) -> double {
return std::exp(a); // k-th derivative of e^x is e^x
};
double x = 1.0;
double a_exp = 0.0;
int terms = 10;
return taylor_approximation(
x, a_exp, terms, [](double a) { return std::exp(a); }, // f(a)
exp_deriv);
}
static void BM_taylor_logger(benchmark::State& state) {
vptyp::Logger l;
l.configure({"size", "apprx", "garbage", "garbage2"});
for (auto _ : state) {
double res = calc_exp_taylor();
l.add("apprx", res);
}
}
static void BM_wo_logger(benchmark::State& state) {
for (auto _ : state)
double res = calc_exp_taylor();
}
BENCHMARK(BM_wo_logger);
BENCHMARK(BM_taylor_logger);
std::string caesar_encoder(const std::string& input) {
static constexpr int small = 141;
static constexpr int big = 101;
std::string encoded;
encoded.reserve(input.size());
for (auto& c : input) {
assert((c - small < 25 && c - small > 0) || (c - big < 25 && c - big > 0));
int id, begin;
if (c - small < 0) {
id = c - big;
begin = big;
} else {
id = c - small;
begin = small;
}
encoded += begin + (id + 3) % 25;
}
return encoded;
}
int caesar_base(int size = 1000) {
std::string a(size, 'a');
auto res = caesar_encoder(a);
return size;
}
static void BM_caesar_wo_logger(benchmark::State& state) {
for (auto _ : state) {
int res = caesar_base();
}
}
static void BM_caesar_logger(benchmark::State& state) {
vptyp::Logger l;
l.configure({"size", "apprx", "garbage", "garbage2"});
for (auto _ : state) {
int res = caesar_base();
l.add("size", res);
}
}
BENCHMARK(BM_caesar_wo_logger);
BENCHMARK(BM_caesar_logger);
#include <random>
#include <type_traits>
static thread_local std::mt19937_64 rng(std::random_device{}());
template <typename T, std::enable_if_t<std::is_integral_v<T>, int> = 0>
std::vector<T> prepareRandData(int size) {
std::uniform_int_distribution<T> dist(1, 1000000);
std::vector<T> result;
for (int i = 0; i < size; ++i) {
result.push_back(dist(rng));
}
return result;
}
template <typename T, std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
std::vector<T> prepareRandData(int size) {
std::uniform_real_distribution<T> dist(1, 1000000);
std::vector<T> result;
for (int i = 0; i < size; ++i) {
result.push_back(dist(rng));
}
return result;
}
static constexpr int arrSize = 1 << 20;
static constexpr int bitmask = arrSize - 1;
static void int64_division(benchmark::State& state) {
std::vector a = prepareRandData<int64_t>(arrSize);
std::vector b = prepareRandData<int64_t>(arrSize);
int64_t i = 0, i2 = 0;
for (auto _ : state) {
benchmark::DoNotOptimize(a[i++ & bitmask] / b[i2++ & bitmask]);
}
}
static void double_division(benchmark::State& state) {
std::vector a = prepareRandData<double>(arrSize);
std::vector b = prepareRandData<double>(arrSize);
int64_t i = 0, i2 = 0;
for (auto _ : state) {
benchmark::DoNotOptimize(a[i++ & bitmask] / b[i2++ & bitmask]);
}
}
static void DoNothing(benchmark::State& state) {
while (state.KeepRunning())
;
}
static void BM_IntDivision(benchmark::State& state) {
volatile int a = 123456789;
volatile int b = 123;
int result;
for (auto _ : state) {
result = a / b;
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(BM_IntDivision);
static void BM_FloatDivision(benchmark::State& state) {
volatile float a = 123456789.0f;
volatile float b = 123.0f;
float result;
for (auto _ : state) {
result = a / b;
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(BM_FloatDivision);
static void BM_DoubleDivision(benchmark::State& state) {
volatile double a = 123456789.0;
volatile double b = 123.0;
double result;
for (auto _ : state) {
result = a / b;
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(BM_DoubleDivision);
BENCHMARK(DoNothing);
BENCHMARK(int64_division);
BENCHMARK(double_division);
BENCHMARK_MAIN();