Search code examples
c++timec++-chrono

How to run a loop for a specified amount of time


I would like to run a piece of code for a specified amount of time. This does not seem to work. Why?

int sec = 5;
auto start = std::chrono::steady_clock::now();
while (std::chrono::duration<double, std::milli>(
          start - std::chrono::steady_clock::now()
       ).count() < sec * 1000)
{
    // do stuff
};

Solution

  • Your specific issues

    Your problem seems to be a reversed subtraction: The loop execution duration is now() - start, not start - now().

    By the way, a little code beautification for you to consider:

    #include <chrono>
    
    int main() {
        auto now = std::chrono::steady_clock::now;
        using namespace std::chrono_literals;
        auto work_duration = 5s;
        auto start = now();
        while ( (now() - start) < work_duration)
        {
            // do stuff
        };
    }
    

    (and this compiles - which is something you should make sure happens for the code in your questions...)

    Generalization

    Let's go a little further, and create a generic function for you for running something for a certain duration:

    #include <chrono>
    
    template <typename F, typename Duration>
    void timed_repeat(F f, Duration execution_duration)
    {
        auto now = std::chrono::steady_clock::now;
        auto stop_time = now() + execution_duration;
        while (now() < stop_time) { f(); };
    }
    
    int main() {
        auto work_duration = std::chrono::seconds{5};
        auto foo = []() {
            // whatever 
        };
        timed_repeat(foo, work_duration);
    }
    

    Important note: Remember that the work duration is "gross" rather than "net", i.e. if your process is preempted by other processes, or just sleeps on I/O, that still counts towards the time spent running the //whatever part. That's true both for your original code snippet and for mine.