I want to get an accurate execution time in micro seconds of my program implemented with C++. I have tried to get the execution time with clock_t but it\'s not accurate.
The new C++11 std::chrono library is one of the most complicated piles of mess I have ever seen or tried to figure out how to use, but at least it is cross-platform!
So, if you'd like to simplify it down and make it more "C-like", including removing all of the type-safe class stuff it does, here's 3 simple and very easy-to-use functions to get timestamps in milliseconds, microseconds, and nanoseconds...that only took me about 12 hrs to write*:
NB: In the code below, you might consider using std::chrono::steady_clock instead of std::chrono::high_resolution_clock. Their definitions from here (https://en.cppreference.com/w/cpp/chrono) are as follows:
- steady_clock (C++11) - monotonic clock that will never be adjusted
- high_resolution_clock (C++11) - the clock with the shortest tick period available
#include
// NB: ALL OF THESE 3 FUNCTIONS BELOW USE SIGNED VALUES INTERNALLY AND WILL EVENTUALLY OVERFLOW (AFTER 200+ YEARS OR
// SO), AFTER WHICH POINT THEY WILL HAVE *SIGNED OVERFLOW*, WHICH IS UNDEFINED BEHAVIOR (IE: A BUG) FOR C/C++.
// But...that's ok...this "bug" is designed into the C++11 specification, so whatever. Your machine won't run for 200
// years anyway...
// Get time stamp in milliseconds.
uint64_t millis()
{
uint64_t ms = std::chrono::duration_cast(std::chrono::high_resolution_clock::
now().time_since_epoch()).count();
return ms;
}
// Get time stamp in microseconds.
uint64_t micros()
{
uint64_t us = std::chrono::duration_cast(std::chrono::high_resolution_clock::
now().time_since_epoch()).count();
return us;
}
// Get time stamp in nanoseconds.
uint64_t nanos()
{
uint64_t ns = std::chrono::duration_cast(std::chrono::high_resolution_clock::
now().time_since_epoch()).count();
return ns;
}
* (Sorry, I've been more of an embedded developer than a standard computer programmer so all this high-level, abstracted static-member-within-class-within-namespace-within-namespace-within-namespace stuff confuses me. Don't worry, I'll get better.)
std::chrono?A: Because C++ programmers like to go crazy with things, so they made it handle units for you. Here's a few cases of some C++ weirdness and uses of std::chrono. Reference this page: https://en.cppreference.com/w/cpp/chrono/duration.
So you can declare a variable of 1 second and change it to microseconds with no cast like this:
// Create a time object of type `std::chrono::seconds` & initialize it to 1 sec
std::chrono::seconds time_sec(1);
// integer scale conversion with no precision loss: no cast
std::cout << std::chrono::microseconds(time_sec).count() << " microseconds\n";
And you can even specify time like this, which is super weird and going way overboard in my opinion. C++14 has literally overloaded the characters ms, us, ns, etc. as function call operators to initialize std::chrono objects of various types like this:
auto time_sec = 1s; // <== notice the 's' inside the code there to specify 's'econds!
// OR:
std::chrono::seconds time_sec = 1s;
// integer scale conversion with no precision loss: no cast
std::cout << std::chrono::microseconds(time_sec).count() << " microseconds\n";
Here's some more examples:
std::chrono::milliseconds time_ms = 1ms;
// OR:
auto time_ms = 1ms;
std::chrono::microseconds time_us = 1us;
// OR:
auto time_us = 1us;
std::chrono::nanoseconds time_ns = 1ns;
// OR:
auto time_ns = 1ns;
Personally, I'd much rather just simplify the language and do this, like I already do, and as has been done in both C and C++ prior to this for decades:
// Notice the `_sec` at the end of the variable name to remind me this
// variable has units of *seconds*!
uint64_t time_sec = 1;
system_clocksteady_clockhigh_resolution_clockutc_clocktai_clockgps_clockfile_clock