user12014522
user12014522

Reputation:

Using Chrono for Time Measurement

I was working with the Chrono library for time measurement. I find out the following code and I know how to use it.

class Timer {
private:
    std::chrono::time_point<std::chrono::high_resolution_clock> pr_StartTime;
    std::chrono::time_point<std::chrono::high_resolution_clock> pr_EndTime;

public:
    Timer() 
    {
        Start();
    }

    ~Timer() 
    {
        Finish();
    }

    void Start() 
    {
        pr_StartTime = std::chrono::high_resolution_clock::now();
    }

    void Finish()
    {
        pr_EndTime = std::chrono::high_resolution_clock::now();

        auto StartTimeMs = std::chrono::time_point_cast<std::chrono::microseconds>(pr_StartTime).time_since_epoch().count();
        auto EndTimeMs = std::chrono::time_point_cast<std::chrono::microseconds>(pr_EndTime).time_since_epoch().count();
        auto Duration = EndTimeMs - StartTimeMs;
        std::cout << "Duration " << Duration << " microseconds." << std::endl;
    }
};

But I didn't realize why the developer used time_since_epoch().count() in casting step. Why we should use time_since_epoch() and count()?

Upvotes: 3

Views: 2489

Answers (1)

Howard Hinnant
Howard Hinnant

Reputation: 219345

Here is a slight rewrite of your Timer. I'll explain each change I made below:

class Timer {
private:
    std::chrono::steady_clock::time_point pr_StartTime;
    std::chrono::steady_clock::time_point pr_EndTime;

public:
    Timer() 
    {
        Start();
    }

    ~Timer() 
    {
        Finish();
    }

    void Start() 
    {
        pr_StartTime = std::chrono::steady_clock::now();
    }

    void Finish()
    {
        using namespace std::chrono;
        pr_EndTime = steady_clock::now();
        auto Duration = duration_cast<microseconds>(pr_EndTime-pr_StartTime);
        std::cout << "Duration " << Duration.count() << " microseconds." << std::endl;
    }
};
  • I switched from high_resolution_clock to steady_clock because high_resolution_clock is always a typedef to either steady_clock or system_clock. See https://stackoverflow.com/a/31553641/576911 for the difference between these two clocks. I prefer to choose either steady_clock or system_clock, so I know what I'm getting.

  • std::chrono::steady_clock::time_point is simply a more concise way to name the type std::chrono::time_point<std::chrono::steady_clock>. Both are correct.

  • When you subtract two time_points, you get a duration. It is simpler to just subtract the time_points, get the duration, and then cast that duration to the desired precision. What you have is not incorrect, just a more convoluted and less safe way to achieve the same result.

  • Unfortunately to print, one must extract the integral value from the Duration with the .count() member function. I avoid doing that until the last statement, as it is akin to a dangerous reinterpret_cast from duration to integral. In C++20, you will no longer have to use .count() to print durations.

  • I prefer to issue a using namespace std::chrono; at function scope instead of writing std::chrono:: multiple times. I simply find it more readable, but this is just my subjective opinion on readability.

Upvotes: 5

Related Questions