Skip to content

Instantly share code, notes, and snippets.

@kodejuice
Created July 30, 2018 22:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kodejuice/8faaccb5b3384d3bbaaedcb134ba64be to your computer and use it in GitHub Desktop.
Save kodejuice/8faaccb5b3384d3bbaaedcb134ba64be to your computer and use it in GitHub Desktop.
A minimal C++ code perfomance tester
/**
A minimal code perfomance tester for C++ that aids in measuring the execution speed of parts of your program,
it reports the (operatations per second) as opposed to the traditional (time taken to run) approach,
the programs repeatedly runs the given function for a couple of seconds,
and returns the number of operations it could perform in a single second (cycles per second).
See Example/Sample usage at bottom of code
*/
#include <bits/stdc++.h>
using namespace std;
template <class T, class... Args> static int run_perft(T, Args...);
template <class T, class... Args> static void warm_up(string, T, Args...);
#define perft(n, x, args...) warm_up(n, x, args);
static double max_cps = 0;
static vector<double> cycles;
static vector<string> tests;
// warm up test function
template <class T, class... Args>
static void warm_up(string testname, T fn, Args... args) {
int cps = 0;
double clk = clock();
while (((double(clock()) - clk)/CLOCKS_PER_SEC)*1e3 < 400) {
fn(args...);
}
cps = run_perft(fn, args...); // run test
cout << "\n+ " << testname << '\n';
cout << " " << cps << " ops/second\n";
cycles.push_back(cps);
tests.push_back(testname);
max_cps = std::max<double>(max_cps, cps);
}
// test runner
template <class T, class... Args>
static int run_perft(T fn, Args... args) {
int cycles = 0;
double clk = clock();
while (((double(clock()) - clk)/CLOCKS_PER_SEC) < 3) {
fn(args...);
cycles += 1;
}
return cycles / 3;
}
// log perft stats
static void perft_stats() {
int c = 0;
streamsize def = cout.precision(2);
cout << '\n';
for (auto v : cycles) {
if (v == max_cps) {
cout << tests[c] << " = fastest\n";
}
else {
cout << tests[c] << " = " << (100-((v/max_cps)*100)) << "% slower\n";
}
c += 1;
}
cout.precision(def);
max_cps = 0, cycles = {}, tests = {};
}
//////////////////
// Simple usage //
//////////////////
// fibonacci iterative - test case 1
int fibonacci_iterative(int n) {
if(n <= 1) return n;
int fib = 1, prevFib = 1, tmp;
for(int i=2; i<n; i++) {
tmp = fib;
fib += prevFib;
prevFib = tmp;
}
return fib;
}
// fibonacci recursive - test case 2
int fibonacci_recursive(int n) {
if(n <= 1) return n;
return fibonacci_recursive(n-1) + fibonacci_recursive(n-2);
}
int main() {
int t = 10;
perft("fibonacci_iterative ", fibonacci_iterative, t);
perft("fibonacci_recursive ", fibonacci_recursive, t);
perft_stats();
}
// Possible output
/*
+ fibonacci_iterative
1384161 ops/second
+ fibonacci_recursive
412086 ops/second
fibonacci_iterative = fastest
fibonacci_recursive = 70% slower
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment