2014-10-01 57 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