Professional C__ - Marc Gregoire [281]
// Write the time to the console
cout << buffer << endl;
Code snippet from Chrono\now.cpp
When you compile the preceding examples with Microsoft Visual Studio, you might get a security-related warning on the call to localtime(). You can get rid of that warning by switching to localtime_s(), but this function is not available on other platforms, such as Linux. On Linux for example, you can switch to localtime_r().
The Chrono library can also be used to time how long it takes for a piece of code to execute. The following example shows how you can do this. The actual type of the variables start and end is system_clock::time_point and the actual type of diff is a duration:
// Get the start time
auto start = system_clock::now();
// Execute code that you want to time
double d = 0;
for (int i = 0; i < 1000000; ++i)
d += sqrt(sin(i) * cos(i));
// Get the end time and calculate the difference
auto end = system_clock::now();
auto diff = end - start;
// Convert the difference into milliseconds and print on the console
cout << duration Code snippet from Chrono\timing.cpp The loop in this example is performing some arithmetic operations with sqrt(), sin(), and cos() to make sure the loop doesn’t end too fast. If you get really small values for the difference in milliseconds on your system, those values will not be accurate and you should increase the number of iterations of the loop to make it last longer. Small timings will not be accurate, because, while timers often have a resolution in milliseconds, on most operating systems, this timer is updated infrequently, for example, every 10ms or 15ms. This induces a phenomenon called gating error, where any event that occurs in less than 1 timer tick appears to take place in zero units of time; any event between 1 and 2 timer ticks appears to take place in 1 timer unit. For example, on a system with a 15ms timer update, a loop that takes 44ms will appear to take only 30ms. When using such timers to time computations, it is important to make sure that the entire computation takes place across a fairly large number of basic timer tick units so that these errors are minimized. Time Point A point in time is represented by the time_point class and stored as a duration relative to the epoch. A time_point is always associated with a certain clock and the epoch is the origin of this associated clock. For example, the epoch for the classic Unix/Linux time is 1st of January 1970, and durations are measured in seconds. The epoch for Windows is 1st of January 1601 and durations are measured in 100 nanosecond units. Other operating systems have different epoch dates and duration units. The time_point class contains a function called time_since_epoch(), which returns a duration representing the time between the epoch of the associated clock and the stored point in time. A time_point supports arithmetic operations that make sense for time points such as +, -, += and -=. Comparison operators are also supported to compare two time points. Two static methods are provided: min() returning the smallest possible point in time, and max() returning the largest possible point in time. The time_point class has three constructors: time_point(): constructs a time_point initialized with duration::zero(). The resulting time_point represents the epoch of the associated clock. time_point(const duration& d): constructs a time_point initialized with the given duration. The resulting time_point represents epoch + d. template Each time_point is associated with a clock. To create a time_point, you specify the clock as the template parameter: time_point Each clock also knows its time_point type, so you can also write it as follows: steady_clock::time_point tp1; The following example demonstrates the time_point class: // Create a time_point representing the epoch // of the