2014-10-01 51 views
1

來自python我試圖找到一種方法來定時調用C++代碼中的幾個函數。到目前爲止,我正在使用這個。多個函數調用的時機

void my_func(/*some args*/) { 
    clock_t t_begin = std::clock(); 
    // code 
    clock_t t_end = std::clock(); 
    double elapsed_secs_U = double(t_end - t_begin)/CLOCKS_PER_SEC; 
} 

但是這是高度重複的。我想有類似功能的包裝,這樣我可以這樣寫:

void timer(func, *args) { 
    clock_t t_begin = std::clock(); 
    func(*args) 
    clock_t t_end = std::clock(); 
    double elapsed_secs_U = double(t_end - t_begin)/CLOCKS_PER_SEC; 
} 

它可以用來像:

timer(compute_a, a, b) 
timer(compute_b, b, c) 

有沒有辦法在C++來實現這一目標?

PS:我需要在生產運行時序,因此,我不想重新編譯代碼才能使用概要分析標誌,並將其粘Valgrind的或任何其他工具

+0

我想你可以做一些[variadic模板](http://en.wikipedia.org/wiki/Variadic_template)這樣做,如果使用[C++ 11] (http://en.wikipedia.org/wiki/C++11)。或者只是一個[預處理器](http://en.wikipedia.org/wiki/C_preprocessor)宏。 – 2014-10-01 07:36:29

回答

4

使用可變參數模板,你可以這樣做:

template <typename F, typename ... Ts> 
void timer(F f, Ts&&...args) { 
    clock_t t_begin = std::clock(); 
    f(std::forward<Ts>(args)...); 
    clock_t t_end = std::clock(); 
    double elapsed_secs_U = double(t_end - t_begin)/CLOCKS_PER_SEC; 
} 

但僅僅

template <typename F> 
void timer(F f) { 
    clock_t t_begin = std::clock(); 
    f(); 
    clock_t t_end = std::clock(); 
    double elapsed_secs_U = double(t_end - t_begin)/CLOCKS_PER_SEC; 
} 

應該做的工作,並通過捕捉拉姆達當你需要傳遞的參數:

timer([&](){ compute_b(b, c);}); 
0

我已經在過去使用這種模式。這會捕捉程序整個生命週期中花費在函數上的總時間,而不是在一次調用中花費的時間。

struct FunctionTimer 
{ 
    FunctionTimer(std::string const& fname) : fname_(fname), totalTime_(0) {} 

    ~FunctionTimer() 
    { 
     std::cout << "Total time in " << fname_ << ": " << totalTime_ << std::endl; 
    } 

    std::string fname_; 
    double totalTime_; 
}; 

struct TimeAccumulator 
{ 
    TimeAccumulator(FunctionTimer& timer) : timer_(timer), begin_(std::clock()) {} 
    ~TimeAccumulator() 
    { 
     clock_t end = std::clock(); 
     double elapsed_secs = double(end - begin_)/CLOCKS_PER_SEC; 
     timer_.totalTime_ += elapsed_secs; 
    } 

    clock_t begin_; 
    FunctionTimer& timer_; 
}; 

void my_func(/*some args*/) 
{ 
    static FunctionTimer timer("my_func"); 
    TimeAccumulator acc(timer); 

    // code 
} 

如果你想創建一個包裝功能,用於提供定時和離開的其餘功能不變,一些模板魔術威力做的伎倆。我必須考慮如何實現這樣的功能模板的細節。

+0

但是我仍然需要修改我所有的funcs,而不是通過'timer(my_func)'調用它們嗎? – greole 2014-10-01 07:53:58

+0

@greole,這是我過去使用的方法。我將這兩行代碼封裝在一個宏中,以便在每個編譯單元的編譯時啓用/禁用它們。 – 2014-10-01 07:58:31