Easily measure elapsed time

前端 未结 26 2601
栀梦
栀梦 2020-11-22 04:13

I am trying to use time() to measure various points of my program.

What I don\'t understand is why the values in the before and after are the same? I understand thi

26条回答
  •  野性不改
    2020-11-22 05:06

    I needed to measure the execution time of individual functions within a library. I didn't want to have to wrap every call of every function with a time measuring function because its ugly and deepens the call stack. I also didn't want to put timer code at the top and bottom of every function because it makes a mess when the function can exit early or throw exceptions for example. So what I ended up doing was making a timer that uses its own lifetime to measure time.

    In this way I can measure the wall-time a block of code took by just instantiating one of these objects at the beginning of the code block in question (function or any scope really) and then allowing the instances destructor to measure the time elapsed since construction when the instance goes out of scope. You can find the full example here but the struct is extremely simple:

    template 
    struct scoped_timer {
      using duration_t = typename clock_t::duration;
      const std::function callback;
      const std::chrono::time_point start;
    
      scoped_timer(const std::function& finished_callback) :
          callback(finished_callback), start(clock_t::now()) { }
      scoped_timer(std::function&& finished_callback) :
          callback(finished_callback), start(clock_t::now()) { }
      ~scoped_timer() { callback(clock_t::now() - start); }
    };
    

    The struct will call you back on the provided functor when it goes out of scope so you can do something with the timing information (print it or store it or whatever). If you need to do something even more complex you could even use std::bind with std::placeholders to callback functions with more arguments.

    Here's a quick example of using it:

    void test(bool should_throw) {
      scoped_timer<> t([](const scoped_timer<>::duration_t& elapsed) {
        auto e = std::chrono::duration_cast>(elapsed).count();
        std::cout << "took " << e << "ms" << std::endl;
      });
    
      std::this_thread::sleep_for(std::chrono::seconds(1));
    
      if (should_throw)
        throw nullptr;
    
      std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    

    If you want to be more deliberate, you can also use new and delete to explicitly start and stop the timer without relying on scoping to do it for you.

提交回复
热议问题