timing of multiple function calls

安稳与你 提交于 2020-01-06 03:53:09

问题


Coming from python I am trying to find a way to time several function calls in a c++ code. So far I am using this.

 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;
 }

But this is highly repetitive. And I would like to have something like a function wrapper so that I can write:

 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;
 }

which could be used like:

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

Is there any way to achieve this in C++?

PS: I need the timings in productive runs, thus I dont want to recompile my code with profiling flags and stick it into Valgrind or any other tool


回答1:


Using variadic template, you may do something like:

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;
}

But simply

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;
}

should do the job, and pass capturing lambda when you need to pass argument:

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



回答2:


I have used this pattern in the past. This captures the total time spent in a function for the entire life of the program, not the time spent in one call.

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
}

If you would like to create a wrapper function for timing purposes and leave the rest of the functions untouched, some template magic might do the trick. I have to think about the details of how such a function template can be implemented.



来源:https://stackoverflow.com/questions/26136319/timing-of-multiple-function-calls

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!