109 lines
3.2 KiB
C++
109 lines
3.2 KiB
C++
#pragma once
|
|
#include <chrono>
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
#include <numeric>
|
|
|
|
template <typename F>
|
|
static void benchmark(std::string name, size_t count, F&& lambda)
|
|
{
|
|
auto start = std::chrono::high_resolution_clock::now();
|
|
|
|
for (size_t i = 0; i < count; i++)
|
|
{
|
|
lambda();
|
|
}
|
|
|
|
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - start);
|
|
long long durationAVG = duration.count() / count;
|
|
|
|
std::cout << "Function " << name << " took avg. " << durationAVG << "us (" << durationAVG / 1000.0f << "ms) over " << count << " runs." << std::endl;
|
|
}
|
|
|
|
|
|
struct BenchResult
|
|
{
|
|
const long long min, max;
|
|
const double mean, median;
|
|
|
|
BenchResult()
|
|
: min(0), max(0), mean(0), median(0)
|
|
{}
|
|
|
|
BenchResult(long long min, long long max, double mean, double median)
|
|
: min(min), max(max), mean(mean), median(median)
|
|
{}
|
|
};
|
|
|
|
template <typename F>
|
|
static BenchResult benchmarkEx(std::string name, size_t count, F&& lambda)
|
|
{
|
|
std::vector<long long> durations(count);
|
|
|
|
for (size_t i = 0; i < count; i++)
|
|
{
|
|
auto start = std::chrono::high_resolution_clock::now();
|
|
lambda();
|
|
auto stop = std::chrono::high_resolution_clock::now();
|
|
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start);
|
|
durations[i] = duration.count();
|
|
}
|
|
|
|
long long min = *std::min_element(durations.begin(), durations.end());
|
|
long long max = *std::max_element(durations.begin(), durations.end());
|
|
double average = std::accumulate(durations.begin(), durations.end(), 0.0) / durations.size();
|
|
|
|
double median;
|
|
std::sort(durations.begin(), durations.end());
|
|
|
|
if (durations.size() % 2 == 0)
|
|
median = (double) (durations[durations.size() / 2 - 1] + durations[durations.size() / 2]) / 2;
|
|
else
|
|
median = (double) durations[durations.size() / 2];
|
|
|
|
std::cout << "Function " << name << " took avg. " << average << "ns (" << average / 1000.0f << "us) over " << count << " runs." << std::endl;
|
|
|
|
return BenchResult(min, max, average, median);
|
|
}
|
|
|
|
struct StopWatch
|
|
{
|
|
typedef std::chrono::high_resolution_clock clock;
|
|
typedef clock::time_point time_point;
|
|
|
|
time_point startTime; // Point in time when start() was called
|
|
time_point lapTime; // Point in time when operator() was called
|
|
|
|
public:
|
|
StopWatch()
|
|
{
|
|
reset();
|
|
}
|
|
|
|
void reset()
|
|
{
|
|
startTime = clock::now();
|
|
lapTime = startTime;
|
|
}
|
|
|
|
std::chrono::microseconds stop()
|
|
{
|
|
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(clock::now() - startTime);
|
|
|
|
std::cout << "Total time: " << duration.count() << "us (" << duration.count() / 1000.0f << "ms)" << std::endl;
|
|
|
|
return duration;
|
|
}
|
|
|
|
void operator()(const std::string& str = "")
|
|
{
|
|
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(clock::now() - lapTime);
|
|
|
|
std::cout << str << (str.empty() ? "" : " ") << "took " << duration.count() << "us (" << duration.count() / 1000.0f << "ms)" << std::endl;
|
|
|
|
lapTime = clock::now();
|
|
}
|
|
};
|