Skip to content

Instantly share code, notes, and snippets.

@gekomad
Last active February 12, 2025 19:08
Show Gist options
  • Save gekomad/b393f4fd4db91226d6b226b4c52aaa5f to your computer and use it in GitHub Desktop.
Save gekomad/b393f4fd4db91226d6b226b4c52aaa5f to your computer and use it in GitHub Desktop.
c++ benchmark
#include "bench.h"
int yourMethod(){
BENCH_AUTO_CLOSE("your_method")
...
}
#pragma once
#include <iostream>
#include "Times.h"
#include <map>
#ifdef BENCH_MODE
#define BENCH_AUTO_CLOSE(name) (Bench(Times::getInstance(),name));
#define BENCH_START(name) (Bench(Times::getInstance(),name));
#define BENCH_SUBPROCESS(name,sub) (Times::getInstance().subProcess(name,sub));
#define BENCH_STOP(name) (Times::getInstance().stop(name));
#define BENCH_PRINT() (Times::getInstance().print());
#else
#define BENCH_AUTO_CLOSE(name)
#define BENCH_START(name)
#define BENCH_SUBPROCESS(name, subProcess)
#define BENCH_STOP(name)
#define BENCH_PRINT()
#endif
using namespace std;
class Bench {
public:
Bench(Times &time, const string &name) {
this->time = &time;
this->name = name;
time.start(name);
}
~Bench() {
time->stop(name);
}
private:
string name;
Times *time;
};
#pragma once
#include <chrono>
#include <iostream>
#include "../../namespaces/String.h"
#include <map>
using namespace std;
using namespace chrono;
class Time {
private:
long _count = 0;
std::chrono::time_point<std::chrono::system_clock> _start;
int64_t _totTime = 0;
map<string, int64_t> subName;
int latency = 0;
public:
Time() {}
Time(int latency) {
this->latency = latency;
}
static constexpr int HOUR_IN_SECONDS = 60 * 60;
static constexpr int HOUR_IN_MINUTES = 60;
long getCount() const { return _count; }
void resetAndStart() {
reset();
start();
}
inline void incCount(const string &subName) {
this->subName[subName]++;
}
inline void start() {
_count++;
_start = std::chrono::system_clock::now();
}
inline void stop() {
_totTime += std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::system_clock::now() - _start).count();
_totTime -= latency;
}
int64_t avg() const {
return _count == 0 ? 0 : _totTime / _count;
}
pair<int64_t, int64_t> avgWithSubProcess(const map<string, Time *> times1) {
int64_t totTimeSubprocess = 0;
for (auto & it : subName) {
auto name1 = it.first;
auto count1 = it.second;
auto avg1 = times1.at(name1)->avg();
totTimeSubprocess += avg1 * count1;
}
auto avgs = pair<int64_t, int64_t>(0, 0);
if (_count)
avgs = pair<int64_t, int64_t>((_totTime - totTimeSubprocess) / _count, _totTime / _count);
return avgs;
}
unsigned long getMill() const {
return _totTime / 1000000;
}
void reset() {
_totTime = _count = 0;
for (auto & it : subName) {
it.second = 0;
}
}
static int diffTime(const high_resolution_clock::time_point t1, const high_resolution_clock::time_point t2) {
const std::chrono::duration<double, std::milli> elapsed = t1 - t2;
return elapsed.count();
}
static string getLocalTime() {
time_t current = chrono::system_clock::to_time_t(chrono::system_clock::now());
auto a = string(ctime(&current));
return a.substr(0, a.size() - 1);
}
};
#pragma once
#include <iostream>
#include "Time.h"
#include <map>
#include <iomanip>
using namespace std;
class Times {
public:
static Times &getInstance() {
static Times i;
return i;
}
private:
int latency;
map<string, Time *> times;
Times() {
for (unsigned i = 0; i < 9999999; i++)calcLatency();
auto a = avg("test");
latency = a.first;
dispose();
}
void dispose() {
for (auto it = times.begin(); it != times.end(); ++it) {
delete it->second;
}
times.clear();
}
~Times() {
dispose();
}
void calcLatency() {
start("test");
stop("test");
}
inline void add(const string &name) {
if (times.end() == times.find(name)) times[name] = new Time(latency);
}
public:
void reset() {
for (auto it = times.begin(); it != times.end(); ++it) it->second->reset();
}
void print() {
int64_t tot = 0;
for (auto it = times.begin(); it != times.end(); ++it) {
const auto count1 = it->second->getCount();
const auto avg1 = avg(it->first);
tot += count1 * avg1.second;
}
for (auto it = times.begin(); it != times.end(); ++it) {
const auto count1 = it->second->getCount();
long countP = count1;
const auto avg1 = avg(it->first);
string m = " ";
if (count1 > (1000 * 1000)) {
countP /= (1000 * 1000);
m = "M";
} else if (count1 > 1000) {
countP /= 1000;
m = "K";
}
cout << "info string bench " << it->first << setw(30 - it->first.length())
<< countP << m << " times\t" << "avg ns:" << "\t"
<< avg1.second << flush;
if (avg1.first != avg1.second)
cout << (avg1.second > 1000 ? "\t" : "\t\t") << "without subprocess: " << avg1.first << flush;
int64_t a = count1 * avg1.second;
int64_t aa = a;
if (a > (1000 * 1000)) {
a /= (1000 * 1000);
m = "M";
} else if (a > 1000) {
a /= 1000;
m = "K";
}
if (avg1.first != avg1.second)
cout << "\t\tTOT: " << a << m << "\t" << (aa * 100 / tot) << "%" << flush;
else
cout << "\t\t\t\t\t\t\t\t\tTOT: " << a << m << "\t" << (aa * 100 / tot) << "%" << flush;
cout << endl;
}
}
inline void subProcess(const string &name, const string &subName) {
times[name]->incCount(subName);
}
inline void start(const string &name) {
add(name);
times[name]->start();
}
inline void stop(const string &name) {
Time *a = times[name];
if (a == nullptr)return;
a->stop();
}
pair<int64_t, int64_t> avg(const string &name) {
Time *a = times[name];
if (a == nullptr)return pair<int64_t, int64_t>(-1, -1);
return a->avgWithSubProcess(times);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment