Last active
February 2, 2020 04:39
-
-
Save ultrasilicon/2228d8f383c57acde5671fb263fcad2c to your computer and use it in GitHub Desktop.
This file contains 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 <iostream> | |
#include <chrono> | |
#include <thread> | |
#include <functional> | |
#include <libagio/function.h> | |
//#define BOUNCE(c,m) bounce<c, decltype(&c::m), &c::m> | |
using namespace std; | |
struct Test { | |
public: | |
void funArg(int input, int plus, int minus) __attribute__ ((optnone)) | |
{ | |
for(int i = 0; i < input + plus - minus; ++ i) | |
asm("nop"); | |
} | |
int a = 0; | |
}; | |
// bounce technique | |
template<typename T, typename MemFun, MemFun f, typename ...Args> | |
constexpr static auto bounce(void* obj, Args... args) | |
-> decltype(((*reinterpret_cast<T*>(obj)).*f)(args...)) | |
{ | |
return ((*reinterpret_cast<T*>(obj)).*f)(args...); | |
} | |
static void callBounce(void (cb)(void *, int, int, int), void * priv, int input, int plus, int minus) | |
{ | |
if(cb) | |
cb(priv, input, plus, minus); | |
} | |
template <typename F> | |
void benchmark(string name, F fun) { | |
auto start_time = std::chrono::high_resolution_clock::now(); | |
for(int i = 0; i < 200000000; i += 1) | |
fun(); | |
auto end_time = std::chrono::high_resolution_clock::now(); | |
std::cout << "{name: " << name << "; time:" | |
<< std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count() / 1000000.0 << "ms}" << std::endl; | |
} | |
int main() | |
{ | |
Test obj; | |
{ | |
benchmark("pure_call__", [&](){ | |
obj.funArg(1, 1, 1); | |
}); | |
} | |
{ | |
using std::placeholders::_1; | |
using std::placeholders::_2; | |
using std::placeholders::_3; | |
std::function<void(int, int, int)> fun = std::bind(&Test::funArg, &obj, _1, _2, _3); | |
benchmark("std_bind___", [&](){ | |
fun(1, 1, 1); | |
}); | |
} | |
{ | |
Agio::CallbackHandler<void(int, int, int)> fun(&obj, &Test::funArg); | |
benchmark("agio_call__", [&](){ | |
fun(1, 1, 1); | |
}); | |
} | |
{ | |
void (*fun)(void *, int, int, int) = bounce<Test, decltype(&Test::funArg), &Test::funArg>; | |
benchmark("bounce_orig", [&](){ | |
callBounce(fun, &obj, 1, 1, 1); | |
}); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment