blob: 922ea27b730d8f08e22b423ce420e4139bcd0478 [file] [log] [blame]
#ifndef BENCHMARK_H
#define BENCHMARK_H
#include <limits>
// Benchmark the operation 'op'. The number of iterations refers to
// how many times the operation is run for each time measurement, the
// result is the minimum over a number of samples runs. The result is the
// amount of time in seconds for one iteration.
#ifdef _WIN32
union _LARGE_INTEGER;
typedef union _LARGE_INTEGER LARGE_INTEGER;
extern "C" int __stdcall QueryPerformanceCounter(LARGE_INTEGER*);
extern "C" int __stdcall QueryPerformanceFrequency(LARGE_INTEGER*);
template <typename F>
double benchmark(int samples, int iterations, F op) {
int64_t freq;
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
double best = std::numeric_limits<double>::infinity();
for (int i = 0; i < samples; i++) {
int64_t t1;
QueryPerformanceCounter((LARGE_INTEGER*)&t1);
for (int j = 0; j < iterations; j++) {
op();
}
int64_t t2;
QueryPerformanceCounter((LARGE_INTEGER*)&t2);
double dt = (t2 - t1) / static_cast<double>(freq);
if (dt < best) best = dt;
}
return best / iterations;
}
#else
#include <chrono>
template <typename F>
double benchmark(int samples, int iterations, F op) {
double best = std::numeric_limits<double>::infinity();
for (int i = 0; i < samples; i++) {
auto t1 = std::chrono::high_resolution_clock::now();
for (int j = 0; j < iterations; j++) {
op();
}
auto t2 = std::chrono::high_resolution_clock::now();
double dt = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count() / 1e6;
if (dt < best) best = dt;
}
return best / iterations;
}
#endif
#endif