194 lines
4.8 KiB
C++
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(); |