Last active
February 12, 2025 19:08
-
-
Save gekomad/b393f4fd4db91226d6b226b4c52aaa5f to your computer and use it in GitHub Desktop.
c++ benchmark
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "bench.h" | |
int yourMethod(){ | |
BENCH_AUTO_CLOSE("your_method") | |
... | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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(¤t)); | |
return a.substr(0, a.size() - 1); | |
} | |
}; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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