The Chrono Library
The <chrono> library contains functions for handling time related things.
The code in these examples uses the C++20 language standard.
Clock Types
Use the system_clock when you want to get the current calendar date and time.
Use the steady_clock when you want to measure time elapsed.
This is likely suitable for many benchmarking needs.
Use the high_resolution_clock for benchmarking and profiling. This may be the
same as the previous two, so it may be better to implement your own high
resolution clock using OS features. This guide will explain how to do this
for Windows and Linux.
Getting The Current Time
Using chrono we can check the current date and time.
1
2
3
4
5
6
7
8
9
10
11
12
|
#include <iostream>
#include <chrono>
using namespace std;
using namespace std::chrono;
int main()
{
time_point<system_clock> t = system_clock::now();
cout << "Current Time: " << t << endl;
}
|
This program will output something like this
1
|
Current Time: 2021-06-18 02:37:59.7503284
|
Measuring Time
It is common to want to measure how much time something takes to run, like for example when benchmarking your code for performance.
For this purpose, we can use the steady_clock to measure time elapsed like a stopwatch.
The Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#include <iostream>
#include <chrono>
#include <thread>
#include <ratio>
using namespace std;
using namespace std::chrono;
using namespace std::chrono_literals;
using std::this_thread::sleep_for;
int main()
{
time_point<steady_clock> startTime = steady_clock::now();
sleep_for(150ms);
time_point<steady_clock> endTime = steady_clock::now();
duration<double> s = endTime - startTime;
duration<double,milli> ms = endTime - startTime;
auto us = duration_cast<microseconds>(endTime - startTime);
auto ns = endTime - startTime;
cout << "Total seconds: " << s.count() << endl;
cout << "Total milliseconds: " << ms.count() << endl;
cout << "Total microseconds: " << us.count() << endl;
cout << "Total nanoseconds: " << ns.count() << endl;
}
|
This program will output something like the following
1
2
3
4
|
Total seconds: 0.162912
Total milliseconds: 162.912
Total microseconds: 162912
Total nanoseconds: 162912300
|
Line By Line
We will first get the current time and then do some lengthy operation to see how long it takes.
1
|
time_point<steady_clock> startTime = steady_clock::now();
|
We will just simulate something taking a long time with the sleep function.
The sleep function will try to sleep for some amount of time, but the actual amount
of time is likely to vary due to system noise.
After the operation we will again obtain the current time.
1
|
time_point<steady_clock> endTime = steady_clock::now();
|
We can then find the total time elapsed by subtracting the start and end times.
For example, if the start time is 9:30AM and the end time is 9:35AM then five minutes have gone by.
This line will get the elapsed time in seconds as a floating point number.
1
|
duration<double> s = endTime - startTime;
|
We can get a different resolution by assigning to a duration
with a different ratio.
This line will get the time in milliseconds as a float.
1
|
duration<double,milli> ms = endTime - startTime;
|
We can get a different resolution with duration_cast.
This line will get the time in microseconds as an integer.
1
|
auto us = duration_cast<microseconds>(endTime - startTime);
|
The default resolution will be integer nanoseconds.
1
|
auto ns = endTime - startTime;
|
The .count() function returns the int or float value of the duration.
A Timer Class
Here is an example time measurement class you can use.
This class provides a slightly nicer more convenience syntax for performance benchmarking your code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
#include <iostream>
#include <chrono>
#include <thread>
#include <ratio>
using namespace std;
using namespace std::chrono;
using namespace std::chrono_literals;
using std::this_thread::sleep_for;
class Stopwatch {
public:
using Clock = steady_clock;
using Time = time_point<Clock>;
using Duration = duration<double,milli>;
private:
Time startTime;
Time endTime;
public:
Stopwatch() {
start();
}
void start() {
startTime = Clock::now();
endTime = startTime;
}
Duration stop() {
endTime = Clock::now();
return get();
}
Duration get() {
return endTime - startTime;
}
};
int main()
{
Stopwatch s;
sleep_for(150ms);
auto totalTime = s.stop();
auto ns = duration_cast<nanoseconds>(totalTime);
cout << "Total milliseconds: " << totalTime.count() << endl;
cout << "Total nanoseconds: " << ns.count() << endl;
}
|
Cover Photo
Credit: Max Shein