calculating time elapsed in C++
Solution 1
Using <chrono>
, the code you need could look like this:
using clock = std::chrono::system_clock;
using sec = std::chrono::duration<double>;
// for milliseconds, use using ms = std::chrono::duration<double, std::milli>;
const auto before = clock::now();
someFunctionToMeasure();
const sec duration = clock::now() - before;
std::cout << "It took " << duration.count() << "s" << std::endl;
NB: Thanks to Howard for his helpful comments for the above.
If you need this snippet multiple times and start/end are approximately entry and exit points of the scope in which you invoke someFunctionToMeasure()
, it might make sense to wrap it into a utility class that makes the two calls to now()
in constructor and destructor.
Solution 2
Just want to throw in the modern approach to timing any callable using <chrono>
and the handy std::invoke
from C++17. Works on members, lambdas or free function, or any other callable.
// Just for convenience
using Seconds = std::chrono::duration<double>;
// Measure how much time the given function takes to execute using chrono
// Pass the function name, then all relevant arguments, including the object as the first if it's a member function
template<typename Function, typename... Args>
Seconds measure(Function&& toTime, Args&&... a)
{
auto start{std::chrono::steady_clock::now()}; // Start timer
std::invoke(std::forward<Function>(toTime), std::forward<Args>(a)...); // Forward and call
auto stop{std::chrono::steady_clock::now()}; // Stop timer
return (stop - start);
}
This will return the time the function took to execute. If you also need the return value, you could make a std::pair
with the Seconds
and the return value since std::invoke
will correctly return what the callable returns.
Then you can use it like this:
auto t1 = measure(normalFunction);
auto t2 = measure(&X::memberFunction, obj, 4);
auto t3 = measure(lambda, 2, 3);
On a free function, member function and lambda respectively.
Solution 3
Source: http://en.cppreference.com/w/cpp/chrono/c/clock
The clock is only keeping track of the time that has passed on the process the clock is executing on. So your sample code is keeping track of how much CPU time it took for your function to execute in. This is notably different from keeping track of real time, because the process your function is running on could be preempted and the cpu could execute other code for some time while your function is waiting to finish.
To answer your second question it may help to clarify what you mean by "better". It sounds like you wanted to track the amount of time that your function executed for, and from my understanding this code accomplishes that task. If you wanted to track the amount of time in real time the other answers give examples of that.
Related videos on Youtube
mereth
Updated on June 04, 2022Comments
-
mereth about 2 years
I need to calculated time elapsed of my function. Right now i am using std::clock and from what i understand this is measuring CPU time, which could be different from real time.
std::clock_t start; double duration; start = std::clock(); someFunctionToMeasure(); duration = (std::clock() - start) / (double)CLOCKS_PER_SEC;
So there are 2 things i'd like to know
How does std::clock exactly work? is it just measuring CPU when its computing that function?
Is there a better way to measure time elapsed of computing my function?
-
Sneftel about 6 yearsPossible duplicate of C++ obtaining milliseconds time on Linux -- clock() doesn't seem to work properly
-
Quimby about 6 yearsuse
chrono
library
-
TMS almost 5 yearsIs the final answer is millseconds or seconds?
-
lubgr almost 5 years@TMS milliseconds.
-
TMS almost 5 yearsBut you are dividing by 1000?
-
lubgr almost 5 years@TMS Sorry, you're right of course. The snippet is actually wrong as it outputs "ms". Let me correct this...
-
Howard Hinnant almost 5 yearsOne could/should implicitly convert once to
duration<double>
instead of explicitly converting to milliseconds and then manually converting to double-based seconds. It is best to let<chrono>
do the conversions for you in order to avoid errors. And once we get C++20, you'll be able to drop the.count() << "s"
. The library will add thes
for you. -
lubgr almost 5 years@HowardHinnant Thanks for the hint, that makes sense! The cast/count() sequence should be clearer now.
-
Howard Hinnant almost 5 yearsLooks much better! This can be further simplified down to
const sec duration = clock::now() - before;
. The advantage to the simplification is that truncation is a source of errors. So if you only useduration_cast
when you are actually truncating, you'll have fewer places to inspect when searching for a bug you think is related to truncation. -
lubgr almost 5 years@HowardHinnant Ok thanks again, I took that into account. Also skimmed through cppref. on the return type of
operator -
for twotime_points
instances, thecommon_type
specialization... which made me realize I've at least one of your<chrono>
talks on my watchlist. I should shift them w.r.t. their priority now :)