[C++] 能否設計一個一般的計時函數?
我有這樣一段 code block:
實現的功能是1. 運行 dmet 下的 _bs_dmet_ () 方法
2. 計時由於我的程序中有好多個地方需要計時,我在想有沒有辦法寫一個函數實現上述功能,但更加 general,比如這樣調用:更一般的,允許有參數,參數用類似 tuple 的數據結構加在後面,如:在 C++ 的框架下這是可能實現的嗎(我知道 python 可以很容易實現)?如果不能,那麼是語言的哪個性質限制了它呢? 提前感謝!!!
void timeit(std::function&
{
Timer t;
t.start();
func();
t.stop();
printf("%.4f secs
", t.seconds();
}
timeit(some_function);
timeit([]{ some_function(arg1, arg2); });
把 陳碩老師的答案稍微改變下 以下代碼基於C++17 標準
template &
decltype(auto) timed_invoke(Callable callable, Args ...args)
{
struct timer{
timer(){
t0 = high_resolution_clock::now();
}
~timer(){
auto t1 = high_resolution_clock::now();
std::cout &<&< (t1 - t0).count() &<&< "nonoseconds.
";
}
time_point&
} t;
return std::invoke(callable, std::forward&
}
int* func0(int x, int y, const char* z) {
return nullptr;
}
void func1(int x, const char* z) {
return;
}
void func2() {
return;
}
template&
void func3(T x) {
return;
}
struct S {
int member_func(int x, float y) {
return x;
}
bool operator()() {
return false;
}
void operator()(int x) {
return;
}
};
int main() {
int* ret = timed_invoke(func0, 1, 2, "hello");
timed_invoke(func1, 1, "hello");
timed_invoke(func2);
timed_invoke(func3&
auto h = timed_invoke([]{return "hello"; }); // lambda
S s;
int r = timed_invoke(S::member_func, s, 1, 2.0f); // member function
bool r0 = timed_invoke(s); // bool S::operator()()
timed_invoke(s, 10); // void S::operator()(int)
}
我還是推薦用傳統c++98,使用scope方案。很多時候,我們不是測試一個函數,而是一段代碼。為啥不用性能分析工具來替代這種入侵式的時間測試呢?
#define START_TIMER() tic()
#define STOP_TIMER(msg) printf("cost time of %s is %lfms
", msg, toc())
#define TIMER_BLOCK(msg) STAERT_TIMER(); auto __stop_timer_on_exit__=make_guard([]{STOP_TIMER(msg)};)
START_TIMER();
some_heavy_func();
STOP_TIMER("some_heavy_func");
{
TIMER_BLOCK("some_heavy_func");
some_heavy_func();
}
- 用宏定義,方便開關,如發布時。
- 用start/end方式時,可以測試代碼段,且不影響測試代碼的作用域,如定義的變數外面非計時代碼還可以用。
class guard_timer
{
public:
guard_timer()
{
m_start = high_resolution_clock::now();
}
~guard_timer()
{
he::get_singleton().life_time += 1s;
milliseconds t = duration_cast&
high_resolution_clock::now() - m_start);
cout &<&< "total time is " &<&< t.count() &<&<"ms." &<&< endl;
}
private:
time_point&
};
#ifdef I_WANT_TIME_IT
#define TIME_IT guard_timer _timer();
#else
#define TIME_IT
#endif
{
TIME_IT;
dmet._bs_dmet();
}
題主的意思是這樣?
template&
T measure_function_time(Ret(*pFunc)(Args...), Args ... args)
{
high_resolution_clock::time_point tp1 = high_resolution_clock::now();
pFunc(args...);
high_resolution_clock::time_point tp2 = high_resolution_clock::now();
duration&
return dur.count();
}
template&
T measure_function_time(Ret(C::*pFunc)(Args...), C* pC, Args ... args)
{
high_resolution_clock::time_point tp1 = high_resolution_clock::now();
(pC-&>*pFunc)(args...);
high_resolution_clock::time_point tp2 = high_resolution_clock::now();
duration&
return dur.count();
}
不過不支持std::function和lambda和std::bind,要支持這幾個還是像陳碩老師那樣用std::function作參數吧。
推薦閱讀:
※unity項目越大編譯速度越慢 ue4用藍圖秒編譯 背後分別的原因是什麼?
※c++的強制類型轉換?
※對於 計算機圖形/界面/可視化/遊戲畫面/遊戲引擎 的疑惑?
※VS編寫C++程序,如何在一個工程裡面創建多個包含main函數的文件?
※c++的单例模式为什么不直接全部使用static,而是非要实例化一个对象?