Measuring execution time of a function in C++ [duplicate]
Asked Answered
R

15

239

I want to find out how much time a certain function takes in my C++ program to execute on Linux. Afterwards, I want to make a speed comparison . I saw several time function but ended up with this from boost. Chrono:

process_user_cpu_clock, captures user-CPU time spent by the current process

Now, I am not clear if I use the above function, will I get the only time which CPU spent on that function?

Secondly, I could not find any example of using the above function. Can any one please help me how to use the above function?

P.S: Right now , I am using std::chrono::system_clock::now() to get time in seconds but this gives me different results due to different CPU load every time.

Represent answered 13/3, 2014 at 18:23 Comment(4)
For Linux use: clock_gettime.. gcc defines other clocks as: typedef system_clock steady_clock; typedef system_clock high_resolution_clock; on Windows, use QueryPerformanceCounter.Shon
I have two implementations of a function and would like to find which performs better.Easy
Very important: make sure you enable optimization. Un-optimized code has different bottlenecks than normal optimized code, and does not tell you anything meaningful. C loop optimization help for final assignment (with compiler optimization disabled). And in general microbenchmarking has many pitfalls, especially failure to do a warm-up loop first for CPU-frequency and page faults: Idiomatic way of performance evaluation?. And this answerCalli
See also How would you benchmark the performance of a function? for Google Benchmark which avoids many of the pitfalls of rolling your own microbenchmark. Also Simple for() loop benchmark takes the same time with any loop bound for more about how optimization interacts with benchmark loops, and what to do about it.Calli
R
433

It is a very easy-to-use method in C++11. You have to use std::chrono::high_resolution_clock from <chrono> header.

Use it like so:

#include <chrono>

/* Only needed for the sake of this example. */
#include <iostream>
#include <thread>
    
void long_operation()
{
    /* Simulating a long, heavy operation. */

    using namespace std::chrono_literals;
    std::this_thread::sleep_for(150ms);
}

int main()
{
    using std::chrono::high_resolution_clock;
    using std::chrono::duration_cast;
    using std::chrono::duration;
    using std::chrono::milliseconds;

    auto t1 = high_resolution_clock::now();
    long_operation();
    auto t2 = high_resolution_clock::now();

    /* Getting number of milliseconds as an integer. */
    auto ms_int = duration_cast<milliseconds>(t2 - t1);

    /* Getting number of milliseconds as a double. */
    duration<double, std::milli> ms_double = t2 - t1;

    std::cout << ms_int.count() << "ms\n";
    std::cout << ms_double.count() << "ms\n";
    return 0;
}

This will measure the duration of the function long_operation.

Possible output:

150ms
150.068ms

Working example: https://godbolt.org/z/oe5cMd

Reimpression answered 13/3, 2014 at 18:30 Comment(17)
When I use this function, on first run it gave me 118440535 microseconds and on second run of the same function it gave me 83221031 microseconds. Shouldn't the two time measurements be equal when I am measuring the duration of that function only ?Represent
No. The processor of your computer can be used less or more. The high_resolution_clock will give you the physical and real time that your function takes to run. So, in your first run, your CPU was being used less than in the next run. By "used" I mean what other application work uses the CPU.Reimpression
In that case, do I need to take multiple readings and take out the average of the time. As I have to do speed comparison of the three different functions?Represent
Yes, if you need the average of the time, that is a good way to get it. take three runs, and calculate the average.Reimpression
BTW, on my computer, the example I provided takes 5 thousand microseconds.Reimpression
Ok.Actually I got those readings when I used high resolution function for my own program function.Represent
Could you please post code without "using namespace" in general. It makes it easier to see what comes from where.Conductivity
Shouldn't this be a steady_clock? Isn't it possible high_resolution_clock could be a non-monotonic clock?Hardset
@Hardset std::chrono::high_resolution_clock offers the is_steady constant and you can check whether it is monotonic or not. Indeed steady_clock is always monotonic, but I guess the user can always check if the implementation of high_resolution_clock is actually monotonic or not, and choose between the twoReimpression
See also example for thread sleep: en.cppreference.com/w/cpp/thread/sleep_forHervey
BTW: I recommend changing long long number to volatile long long number. Otherwise, the optimizer will likely optimize away that loop and you will get a running time of zero.Forwarder
Or compile with -O0 just for the purpose of this testing :)Reimpression
@BobbieE.Ray all these classes are brought via using X, not via using namespace. An older version of the answer had using namespace, but not the current one.Reimpression
Just to clarify if you don't want to use using X as it can be a bit confusing, it's std::chrono::high_resolution_clock, std::chrono::duration<double, std::milli> and std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1). Thanks @Victor!Marcelinomarcell
@Conductivity using namespace std::chrono_literals; is the only way to use them (the chrono literals) and is much more readable than using std::chrono::duration<double, std::ratio<1,1>> paf {150e-3};Journalist
Related: stackoverflow.com/questions/37786547/…Devisal
std::endl forgotDunk
T
33

Here's a function that will measure the execution time of any function passed as argument:

#include <chrono>
#include <utility>

typedef std::chrono::high_resolution_clock::time_point TimeVar;

#define duration(a) std::chrono::duration_cast<std::chrono::nanoseconds>(a).count()
#define timeNow() std::chrono::high_resolution_clock::now()

template<typename F, typename... Args>
double funcTime(F func, Args&&... args){
    TimeVar t1=timeNow();
    func(std::forward<Args>(args)...);
    return duration(timeNow()-t1);
}

Example usage:

#include <iostream>
#include <algorithm>

typedef std::string String;

//first test function doing something
int countCharInString(String s, char delim){
    int count=0;
    String::size_type pos = s.find_first_of(delim);
    while ((pos = s.find_first_of(delim, pos)) != String::npos){
        count++;pos++;
    }
    return count;
}

//second test function doing the same thing in different way
int countWithAlgorithm(String s, char delim){
    return std::count(s.begin(),s.end(),delim);
}


int main(){
    std::cout<<"norm: "<<funcTime(countCharInString,"precision=10",'=')<<"\n";
    std::cout<<"algo: "<<funcTime(countWithAlgorithm,"precision=10",'=');
    return 0;
}

Output:

norm: 15555
algo: 2976
Turnover answered 24/11, 2015 at 17:49 Comment(16)
@RestlessC0bra : It's implementaion defined, high_resolution_clock may be an alias of system_clock (wall clock), steady_clock or a third independent clock. See details here. For cpu clock, std::clock may be usedTurnover
Two macros and a global typedef - none of which safe a single keytroke - is certainly nothing I'd call elegant.Also passing a function object and perfectly forwarding the arguments separately is a bit of an overkill (and in the case of overloaded functions even inconvenient), when you can just require the timed code to be put in a lambda. But well, as long as passing arguments is optional.Masao
@Masao : timeNow() is called twice, now calculate how many keystrokes are saved, and yeah, think about readability too.Turnover
You are right, my mistake. That one (out of three) does save some keystrokes. Still no reason to use macros or global typedefs for something that is only used within a single functionMasao
@Masao : Indeed it's a single function here, but if you broaden your vision a little, you can see how easy it can make measuring times of different code segments. For example, I use those three to measure execution times of code segments inside a function or global scope. Those macros and teypedef do come in handy.Turnover
And this is a justification for violating each and every guideline about the naming of macros? You don't prefix them, you don't use capital letters, you pick a very common name that has a high probability of colliding with some local symbol and most of all: Why are you using a macro at all (instead of a function)? And while we are at it: Why are you returning the duration as a double representing nanoseconds in the first place? We should probably agree that we disagree. My original opinion stands: "This is not what I'd call elegant code".Masao
@Masao : All caps? C++ standard itself violates that so called naming convention (e.g assert), and also where's the prefix in assert? common name? remember that you are the one that will be coding that thing, if you are worried about conflicting a yourself-defined name like fooWhatever, you should stop coding and do something else instead (because in coding you will have to define lots of names, how dangerous!!!, LOL). Your time will be better spent elsewhere. Then again, agreed to disagree.Turnover
The problem is they are unscoped.What I'm worried about is that such macros end up in a header file that gets(maybe indirectly as part of a library) included in my code.If you want to have a taste of what happens if common names are used for macros,include windows.h in a non-trivial c++ project. Regarding assert first of all: "quod licet iovi non licet bovi" ;). Second, not all decision in the standard library (sometimes dating back decades) are actually considered a good idea by modern standards. There is a reason,why the c++ modules designer try very hard not to export macros by default.Masao
... In case this is not clear: My beef is not with you having something that is called e.g. timeNow() or duration, but that it is a macro, when a normal function that would obey normal lookup rules and namespaces would do just fine. And the typedef could be local to the funcTime function, as it isn't used anywhere else - or you could just use auto and not need a typedef at all.Masao
@Masao : Good point, making this a header would definitely be a bad idea. Though, in the end, it's just an example, if you have complex needs you gotta think about standard practices and adapt the code accordingly. For example, when writing code, I make it convenient for me when it's in the cpp file I am working right now, but when it's time to move it elsewhere I take every necessary steps to make it robust so that I don't have to look at it again. And I think that, every programmer out there who are not complete noobs think broadly when the time is due. Hope, I clarified my point :D.Turnover
@Jahid: Thanks. In that case consider my comments void and null.Masao
@Turnover I have a class member function with no arguments and return type is void. Could you please let me know how to use this mechanism for my case, currenly it give compiler errorButterfingers
@Turnover How do you intend to get the function return value?Creatural
@T.s.Arun : Use a pointer to store the return value inside funcTime()Turnover
Using class methods give errors like using invalid usage of non-static member function. How would you suggest to cope with that?Egmont
how do i return the return value of the function tho?, how to use a template to refer to the return type of funcBohlin
O
15

In Scott Meyers book I found an example of universal generic lambda expression that can be used to measure function execution time. (C++14)

auto timeFuncInvocation = 
    [](auto&& func, auto&&... params) {
        // get time before function invocation
        const auto& start = std::chrono::high_resolution_clock::now();
        // function invocation using perfect forwarding
        std::forward<decltype(func)>(func)(std::forward<decltype(params)>(params)...);
        // get time after function invocation
        const auto& stop = std::chrono::high_resolution_clock::now();
        return stop - start;
     };

The problem is that you are measure only one execution so the results can be very differ. To get a reliable result you should measure a large number of execution. According to Andrei Alexandrescu lecture at code::dive 2015 conference - Writing Fast Code I:

Measured time: tm = t + tq + tn + to

where:

tm - measured (observed) time

t - the actual time of interest

tq - time added by quantization noise

tn - time added by various sources of noise

to - overhead time (measuring, looping, calling functions)

According to what he said later in the lecture, you should take a minimum of this large number of execution as your result. I encourage you to look at the lecture in which he explains why.

Also there is a very good library from google - https://github.com/google/benchmark. This library is very simple to use and powerful. You can checkout some lectures of Chandler Carruth on youtube where he is using this library in practice. For example CppCon 2017: Chandler Carruth “Going Nowhere Faster”;

Example usage:

#include <iostream>
#include <chrono>
#include <vector>
auto timeFuncInvocation = 
    [](auto&& func, auto&&... params) {
        // get time before function invocation
        const auto& start = high_resolution_clock::now();
        // function invocation using perfect forwarding
        for(auto i = 0; i < 100000/*largeNumber*/; ++i) {
            std::forward<decltype(func)>(func)(std::forward<decltype(params)>(params)...);
        }
        // get time after function invocation
        const auto& stop = high_resolution_clock::now();
        return (stop - start)/100000/*largeNumber*/;
     };

void f(std::vector<int>& vec) {
    vec.push_back(1);
}

void f2(std::vector<int>& vec) {
    vec.emplace_back(1);
}
int main()
{
    std::vector<int> vec;
    std::vector<int> vec2;
    std::cout << timeFuncInvocation(f, vec).count() << std::endl;
    std::cout << timeFuncInvocation(f2, vec2).count() << std::endl;
    std::vector<int> vec3;
    vec3.reserve(100000);
    std::vector<int> vec4;
    vec4.reserve(100000);
    std::cout << timeFuncInvocation(f, vec3).count() << std::endl;
    std::cout << timeFuncInvocation(f2, vec4).count() << std::endl;
    return 0;
}

EDIT: Ofcourse you always need to remember that your compiler can optimize something out or not. Tools like perf can be useful in such cases.

Octamerous answered 27/11, 2018 at 11:18 Comment(4)
Interesting -- what's the benefit of using a lambda here over a function template?Pain
Main difference would be that it is a callable object but indeed you can get something very similar with variadic template and std::result_of_t.Octamerous
@KrzysztofSommerfeld How to do this one for function methods , when I pass the timing(Object.Method1) it return error "non-standard syntax; use '&' to create a pointer to member"Butterfingers
timeFuncInvocation([&objectName](auto&&... args){ objectName.methodName(std::forward<decltype(args)>(args)...); }, arg1, arg2,...); or ommit & sign before objectName (then you will have a copy of the object)Octamerous
H
12

simple program to find a function execution time taken.

#include <iostream>
#include <ctime> // time_t
#include <cstdio>

void function()
{
     for(long int i=0;i<1000000000;i++)
     {
        // do nothing
     }
}

int main()
{

time_t begin,end; // time_t is a datatype to store time values.

time (&begin); // note time before execution
function();
time (&end); // note time after execution

double difference = difftime (end,begin);
printf ("time taken for function() %.2lf seconds.\n", difference );

return 0;
}
Heartrending answered 2/11, 2016 at 12:35 Comment(2)
it's very inaccurate, shows only seconds, but no millisecondsPathoneurosis
You should rather use something like clock_gettime and process the results within a struct timespec result. But this is a C solution rather than a C++ one.Reimpression
W
8

Easy way for older C++, or C:

#include <time.h> // includes clock_t and CLOCKS_PER_SEC

int main() {

    clock_t start, end;

    start = clock();
    // ...code to measure...
    end = clock();

    double duration_sec = double(end-start)/CLOCKS_PER_SEC;
    return 0;
}

Timing precision in seconds is 1.0/CLOCKS_PER_SEC

Weikert answered 1/9, 2018 at 16:45 Comment(3)
This is not portable. It measures processor time on Linux, and clock time on Windows.Funerary
start and end time are always the same, despite I add an array of 512 elements..... under Win64/Visual Studio 17Resistance
I'm not sure what would cause that, but if you're using C++ then best to switch over to the standard <chrono> methods.Weikert
F
6
#include <iostream>
#include <chrono>

void function()
{
    // code here;
}

int main()
{
    auto t1 = std::chrono::high_resolution_clock::now();
    function();
    auto t2 = std::chrono::high_resolution_clock::now();

    auto duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();

    std::cout << duration<<"/n";
    return 0;
}

This Worked for me.


Note:

The high_resolution_clock is not implemented consistently across different standard library implementations, and its use should be avoided. It is often just an alias for std::chrono::steady_clock or std::chrono::system_clock, but which one it is depends on the library or configuration. When it is a system_clock, it is not monotonic (e.g., the time can go backwards).

For example, for gcc's libstdc++ it is system_clock, for MSVC it is steady_clock, and for clang's libc++ it depends on configuration.

Generally one should just use std::chrono::steady_clock or std::chrono::system_clock directly instead of std::chrono::high_resolution_clock: use steady_clock for duration measurements, and system_clock for wall-clock time.

Floridafloridia answered 23/12, 2020 at 11:38 Comment(0)
T
4

Here is an excellent header only class template to measure the elapsed time of a function or any code block:

#ifndef EXECUTION_TIMER_H
#define EXECUTION_TIMER_H

template<class Resolution = std::chrono::milliseconds>
class ExecutionTimer {
public:
    using Clock = std::conditional_t<std::chrono::high_resolution_clock::is_steady,
                                     std::chrono::high_resolution_clock,
                                     std::chrono::steady_clock>;
private:
    const Clock::time_point mStart = Clock::now();

public:
    ExecutionTimer() = default;
    ~ExecutionTimer() {
        const auto end = Clock::now();
        std::ostringstream strStream;
        strStream << "Destructor Elapsed: "
                  << std::chrono::duration_cast<Resolution>( end - mStart ).count()
                  << std::endl;
        std::cout << strStream.str() << std::endl;
    }    

    inline void stop() {
        const auto end = Clock::now();
        std::ostringstream strStream;
        strStream << "Stop Elapsed: "
                  << std::chrono::duration_cast<Resolution>(end - mStart).count()
                  << std::endl;
        std::cout << strStream.str() << std::endl;
    }

}; // ExecutionTimer

#endif // EXECUTION_TIMER_H

Here are some uses of it:

int main() {
    { // empty scope to display ExecutionTimer's destructor's message
         // displayed in milliseconds
         ExecutionTimer<std::chrono::milliseconds> timer;

         // function or code block here

         timer.stop();

    } 

    { // same as above
        ExecutionTimer<std::chrono::microseconds> timer;

        // code block here...

        timer.stop();
    }

    {  // same as above
       ExecutionTimer<std::chrono::nanoseconds> timer;

       // code block here...

       timer.stop();

    }

    {  // same as above
       ExecutionTimer<std::chrono::seconds> timer;

       // code block here...

       timer.stop();

    }              

    return 0;
}

Since the class is a template we can specify real easily in how we want our time to be measured & displayed. This is a very handy utility class template for doing bench marking and is very easy to use.

Trinia answered 12/1, 2018 at 6:18 Comment(6)
Personally, the stop() member function isn't needed because the destructor stops the timer for you.Brader
@Brader The design of the class doesn't necessarily need the stop function, however it is there for a specific reason. The default construct when creating the object before your test code starts the timer. Then after your test code you explicitly use the timer object and call its stop method. You have to invoke it manually when you want to stop the timer. The class doesn't take any parameters. Also if you used this class just as I've shown you will see that there is a minimal elapse of time between the call to obj.stop and its destructor.Trinia
@Brader ... This also allows to have multiple timer objects within the same scope, not that one would really need it, but just another viable option.Trinia
This example cannot be compiled in the presented form. The error is related to "no match for operator<< ..."!Pedicure
@Pedicure do you have to appropriate includes; such as <chrono>?Trinia
It was a missing include, can’t check it right now but I think it was <iomanip>. I was trying adding ostream, iostream etc. It was hard to find the right one!Pedicure
D
3

If you want to safe time and lines of code you can make measuring the function execution time a one line macro:

a) Implement a time measuring class as already suggested above ( here is my implementation for android):

class MeasureExecutionTime{
private:
    const std::chrono::steady_clock::time_point begin;
    const std::string caller;
public:
    MeasureExecutionTime(const std::string& caller):caller(caller),begin(std::chrono::steady_clock::now()){}
    ~MeasureExecutionTime(){
        const auto duration=std::chrono::steady_clock::now()-begin;
        LOGD("ExecutionTime")<<"For "<<caller<<" is "<<std::chrono::duration_cast<std::chrono::milliseconds>(duration).count()<<"ms";
    }
};

b) Add a convenient macro that uses the current function name as TAG (using a macro here is important, else __FUNCTION__ will evaluate to MeasureExecutionTime instead of the function you wanto to measure

#ifndef MEASURE_FUNCTION_EXECUTION_TIME
#define MEASURE_FUNCTION_EXECUTION_TIME const MeasureExecutionTime measureExecutionTime(__FUNCTION__);
#endif

c) Write your macro at the begin of the function you want to measure. Example:

 void DecodeMJPEGtoANativeWindowBuffer(uvc_frame_t* frame_mjpeg,const ANativeWindow_Buffer& nativeWindowBuffer){
        MEASURE_FUNCTION_EXECUTION_TIME
        // Do some time-critical stuff 
}

Which will result int the following output:

ExecutionTime: For DecodeMJPEGtoANativeWindowBuffer is 54ms

Note that this (as all other suggested solutions) will measure the time between when your function was called and when it returned, not neccesarily the time your CPU was executing the function. However, if you don't give the scheduler any change to suspend your running code by calling sleep() or similar there is no difference between.

Durant answered 19/5, 2020 at 8:37 Comment(0)
D
2
  • It is a very easy to use method in C++11.
  • We can use std::chrono::high_resolution_clock from header
  • We can write a method to print the method execution time in a much readable form.

For example, to find the all the prime numbers between 1 and 100 million, it takes approximately 1 minute and 40 seconds. So the execution time get printed as:

Execution Time: 1 Minutes, 40 Seconds, 715 MicroSeconds, 715000 NanoSeconds

The code is here:

#include <iostream>
#include <chrono>

using namespace std;
using namespace std::chrono;

typedef high_resolution_clock Clock;
typedef Clock::time_point ClockTime;

void findPrime(long n, string file);
void printExecutionTime(ClockTime start_time, ClockTime end_time);

int main()
{
    long n = long(1E+8);  // N = 100 million

    ClockTime start_time = Clock::now();

    // Write all the prime numbers from 1 to N to the file "prime.txt"
    findPrime(n, "C:\\prime.txt"); 

    ClockTime end_time = Clock::now();

    printExecutionTime(start_time, end_time);
}

void printExecutionTime(ClockTime start_time, ClockTime end_time)
{
    auto execution_time_ns = duration_cast<nanoseconds>(end_time - start_time).count();
    auto execution_time_ms = duration_cast<microseconds>(end_time - start_time).count();
    auto execution_time_sec = duration_cast<seconds>(end_time - start_time).count();
    auto execution_time_min = duration_cast<minutes>(end_time - start_time).count();
    auto execution_time_hour = duration_cast<hours>(end_time - start_time).count();

    cout << "\nExecution Time: ";
    if(execution_time_hour > 0)
    cout << "" << execution_time_hour << " Hours, ";
    if(execution_time_min > 0)
    cout << "" << execution_time_min % 60 << " Minutes, ";
    if(execution_time_sec > 0)
    cout << "" << execution_time_sec % 60 << " Seconds, ";
    if(execution_time_ms > 0)
    cout << "" << execution_time_ms % long(1E+3) << " MicroSeconds, ";
    if(execution_time_ns > 0)
    cout << "" << execution_time_ns % long(1E+6) << " NanoSeconds, ";
}
Delius answered 16/11, 2018 at 15:11 Comment(0)
H
2

I recommend using steady_clock which is guarunteed to be monotonic, unlike high_resolution_clock.

#include <iostream>
#include <chrono>

using namespace std;

unsigned int stopwatch()
{
    static auto start_time = chrono::steady_clock::now();

    auto end_time = chrono::steady_clock::now();
    auto delta    = chrono::duration_cast<chrono::microseconds>(end_time - start_time);

    start_time = end_time;

    return delta.count();
}

int main() {
  stopwatch(); //Start stopwatch
  std::cout << "Hello World!\n";
  cout << stopwatch() << endl; //Time to execute last line
  for (int i=0; i<1000000; i++)
      string s = "ASDFAD";
  cout << stopwatch() << endl; //Time to execute for loop
}

Output:

Hello World!
62
163514
Hardset answered 16/8, 2019 at 14:51 Comment(0)
C
1

Since none of the provided answers are very accurate or give reproducable results I decided to add a link to my code that has sub-nanosecond precision and scientific statistics.

Note that this will only work to measure code that takes a (very) short time to run (aka, a few clock cycles to a few thousand): if they run so long that they are likely to be interrupted by some -heh- interrupt, then it is clearly not possible to give a reproducable and accurate result; the consequence of which is that the measurement never finishes: namely, it continues to measure until it is statistically 99.9% sure it has the right answer which never happens on a machine that has other processes running when the code takes too long.

https://github.com/CarloWood/cwds/blob/master/benchmark.h#L40

Constantino answered 2/4, 2020 at 12:25 Comment(0)
R
1

Use std::chrono::steady_clock and not std::chrono::system_clock for measuring run time in C++11. The reason is (quoting system_clock's documentation):

on most systems, the system time can be adjusted at any moment

while steady_clock is monotonic and is better suited for measuring intervals:

Class std::chrono::steady_clock represents a monotonic clock. The time points of this clock cannot decrease as physical time moves forward. This clock is not related to wall clock time, and is best suitable for measuring intervals.

Here's an example:

auto start = std::chrono::steady_clock::now();
// do something
auto finish = std::chrono::steady_clock::now();
double elapsed_seconds = std::chrono::duration_cast<
  std::chrono::duration<double>>(finish - start).count();

Practical tip: if you are measuring run time and want to report seconds std::chrono::duration_cast<std::chrono::seconds> is rarely what you need because it gives you whole number of seconds. To get the time in seconds as a double use the example above.

For even more reliable results consider using a benchmarking framework such as Google Benchmark.

I would not recommend using std::chrono::high_resolution_clock because it is not guaranteed to be monotonic.

Rosenthal answered 28/12, 2023 at 4:56 Comment(0)
F
0

You can have a simple class which can be used for this kind of measurements.

class duration_printer {
public:
    duration_printer() : __start(std::chrono::high_resolution_clock::now()) {}
    ~duration_printer() {
        using namespace std::chrono;
        high_resolution_clock::time_point end = high_resolution_clock::now();
        duration<double> dur = duration_cast<duration<double>>(end - __start);
        std::cout << dur.count() << " seconds" << std::endl;
    }
private:
    std::chrono::high_resolution_clock::time_point __start;
};

The only thing is needed to do is to create an object in your function at the beginning of that function

void veryLongExecutingFunction() {
    duration_calculator dc;
    for(int i = 0; i < 100000; ++i) std::cout << "Hello world" << std::endl;
}

int main() {
    veryLongExecutingFunction();
    return 0;
}

and that's it. The class can be modified to fit your requirements.

Fortunio answered 22/2, 2020 at 20:35 Comment(0)
N
0

C++11 cleaned up version of Jahid's response:

#include <chrono>
#include <thread>

void long_operation(int ms)
{
    /* Simulating a long, heavy operation. */
    std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}

template<typename F, typename... Args>
double funcTime(F func, Args&&... args){
    std::chrono::high_resolution_clock::time_point t1 = 
        std::chrono::high_resolution_clock::now();
    func(std::forward<Args>(args)...);
    return std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::high_resolution_clock::now()-t1).count();
}

int main()
{
    std::cout<<"expect 150: "<<funcTime(long_operation,150)<<"\n";

    return 0;
}
Nidia answered 15/5, 2021 at 17:4 Comment(0)
I
0

This is a very basic timer class which you can expand on depending on your needs. I wanted something straightforward which can be used cleanly in code. You can mess with it at coding ground with this link: http://tpcg.io/nd47hFqr.

class local_timer {
    private:
        std::chrono::_V2::system_clock::time_point start_time;
        std::chrono::_V2::system_clock::time_point stop_time;
        std::chrono::_V2::system_clock::time_point stop_time_temp;
        std::chrono::microseconds most_recent_duration_usec_chrono;
        double most_recent_duration_sec;
    public:

        local_timer() {

        };

        ~local_timer() {

        };

        void start() {
            this->start_time = std::chrono::high_resolution_clock::now();
        };

        void stop() {
            this->stop_time = std::chrono::high_resolution_clock::now();
        };

        double get_time_now() {
            this->stop_time_temp = std::chrono::high_resolution_clock::now();
            this->most_recent_duration_usec_chrono = std::chrono::duration_cast<std::chrono::microseconds>(stop_time_temp-start_time);
            this->most_recent_duration_sec = (long double)most_recent_duration_usec_chrono.count()/1000000;
            return this->most_recent_duration_sec;
        };

        double get_duration() {
            this->most_recent_duration_usec_chrono = std::chrono::duration_cast<std::chrono::microseconds>(stop_time-start_time);
            this->most_recent_duration_sec = (long double)most_recent_duration_usec_chrono.count()/1000000;
            return this->most_recent_duration_sec;
        };


};

The use for this being

#include <iostream>
#include "timer.hpp" //if kept in an hpp file in the same folder, can also before your main function

int main() {
    //create two timers
    local_timer timer1 = local_timer();
    local_timer timer2 = local_timer();
    
    //set start time for timer1
    timer1.start();
    //wait 1 second
    while(timer1.get_time_now() < 1.0) {
    }
    //save time
    timer1.stop();
    //print time
    std::cout << timer1.get_duration() << " seconds, timer 1\n" << std::endl;

    timer2.start();
    for(long int i = 0; i < 100000000; i++) {
        //do something
        if(i%1000000 == 0) { 
            //return time since loop started
            std::cout << timer2.get_time_now() << " seconds, timer 2\n"<< std::endl;
        }
        
    }
    return 0;
}
Itinerary answered 14/6, 2021 at 18:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.