231

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.

Jahid
  • 21,542
  • 10
  • 90
  • 108
Xara
  • 8,748
  • 16
  • 52
  • 82
  • 2
    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`. – Brandon Mar 13 '14 at 18:39
  • Isn't this question a duplicate of [this one](https://stackoverflow.com/questions/12340824/how-to-compare-performance-of-two-pieces-of-codes?answertab=votes#tab-top) or do the scenarios make the solutions different? – northerner Jan 23 '19 at 18:55
  • I have two implementations of a function and would like to find which performs better. – northerner Jan 23 '19 at 18:55
  • 2
    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)](https://stackoverflow.com/a/32001196). 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?](https://stackoverflow.com/q/60291987). And [this answer](https://stackoverflow.com/a/50934895/224132) – Peter Cordes Apr 25 '20 at 21:57
  • 1
    See also [How would you benchmark the performance of a function?](https://stackoverflow.com/q/35725050) 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](https://stackoverflow.com/a/50934895) for more about how optimization interacts with benchmark loops, and what to do about it. – Peter Cordes Apr 25 '20 at 22:19

14 Answers14

424

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

Andreas Florath
  • 4,418
  • 22
  • 32
Victor
  • 13,914
  • 19
  • 78
  • 147
  • 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 ? – Xara Mar 13 '14 at 18:48
  • 5
    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. – Victor Mar 13 '14 at 18:50
  • 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? – Xara Mar 13 '14 at 18:53
  • 2
    Yes, if you need the average of the time, that is a good way to get it. take three runs, and calculate the average. – Victor Mar 13 '14 at 18:54
  • BTW, on my computer, the example I provided takes 5 thousand microseconds. – Victor Mar 13 '14 at 18:56
  • Ok.Actually I got those readings when I used high resolution function for my own program function. – Xara Mar 13 '14 at 18:59
  • 36
    Could you please post code without "using namespace" in general. It makes it easier to see what comes from where. – Snowman Mar 19 '19 at 17:38
  • 4
    Shouldn't this be a `steady_clock`? Isn't it possible `high_resolution_clock` could be a non-monotonic clock? – Gillespie Aug 16 '19 at 14:36
  • @Gillespie `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 two – Victor Aug 17 '19 at 14:37
  • See also example for thread sleep: https://en.cppreference.com/w/cpp/thread/sleep_for – Gunnar Bernstein Sep 01 '19 at 16:49
  • 2
    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. – Kai Petzke Feb 28 '21 at 21:24
  • 1
    Or compile with `-O0` just for the purpose of this testing :) – Victor Mar 01 '21 at 10:57
  • 1
    @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. – Victor Sep 16 '21 at 13:03
  • 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` and `std::chrono::duration_cast(t2 - t1)`. Thanks @Victor! – Bobbie E. Ray Sep 17 '21 at 07:23
  • @Snowman `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> paf {150e-3};` – Antoine Viallon Oct 30 '21 at 18:35
  • Related: https://stackoverflow.com/questions/37786547/enforcing-statement-order-in-c – ridilculous Dec 13 '22 at 15:49
  • `std::endl` forgot –  Jun 08 '23 at 11:22
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
Zitrax
  • 19,036
  • 20
  • 88
  • 110
Jahid
  • 21,542
  • 10
  • 90
  • 108
  • 4
    @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](http://en.cppreference.com/w/cpp/chrono/high_resolution_clock). For cpu clock, `std::clock` may be used – Jahid Jan 24 '17 at 11:39
  • 2
    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. – MikeMB Mar 03 '17 at 12:30
  • @MikeMB : `timeNow()` is called twice, now calculate how many keystrokes are saved, and yeah, think about readability too. – Jahid May 07 '17 at 22:51
  • 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 function – MikeMB May 07 '17 at 23:10
  • @MikeMB : 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. – Jahid May 08 '17 at 09:35
  • 2
    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". – MikeMB May 08 '17 at 20:44
  • @MikeMB : 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. – Jahid May 09 '17 at 05:57
  • 1
    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. – MikeMB Jun 20 '17 at 08:44
  • 1
    `...` 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. – MikeMB Jun 20 '17 at 08:47
  • 4
    @MikeMB : 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. – Jahid Jun 20 '17 at 08:58
  • 2
    @Jahid: Thanks. In that case consider my comments void and null. – MikeMB Jun 20 '17 at 09:00
  • @Jahid 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 error – RobinAtTech Dec 13 '19 at 00:52
  • @Jahid How do you intend to get the function return value? – T.s. Arun Dec 19 '19 at 10:58
  • 1
    @T.s.Arun : Use a pointer to store the return value inside `funcTime()` – Jahid Dec 21 '19 at 07:34
  • Using class methods give errors like using `invalid usage of non-static member function`. How would you suggest to cope with that? – Saurav Apr 13 '21 at 12:58
  • how do i return the return value of the function tho?, how to use a template to refer to the return type of func – ihsan Dec 20 '22 at 09:26
14

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.

  • Interesting -- what's the benefit of using a lambda here over a function template? – user48956 Feb 11 '19 at 19:23
  • 1
    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. – Krzysztof Sommerfeld Feb 14 '19 at 10:11
  • @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" – RobinAtTech Dec 13 '19 at 01:12
  • timeFuncInvocation([&objectName](auto&&... args){ objectName.methodName(std::forward(args)...); }, arg1, arg2,...); or ommit & sign before objectName (then you will have a copy of the object) – Krzysztof Sommerfeld Dec 16 '19 at 12:28
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;
}
Abdullah Farweez
  • 851
  • 2
  • 11
  • 25
  • 9
    it's very inaccurate, shows only seconds, but no milliseconds – user25 May 17 '18 at 19:59
  • 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. – Victor Nov 19 '20 at 10:24
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

v.chaplin
  • 617
  • 6
  • 8
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.

myeongkil kim
  • 2,465
  • 4
  • 16
  • 22
Ranjeet R Patil
  • 453
  • 6
  • 10
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.

Francis Cugler
  • 7,788
  • 2
  • 28
  • 59
  • Personally, the `stop()` member function isn't needed because the destructor stops the timer for you. – Casey Feb 22 '18 at 13:59
  • 1
    @Casey 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`. – Francis Cugler Feb 23 '18 at 03:15
  • @Casey ... This also allows to have multiple timer objects within the same scope, not that one would really need it, but just another viable option. – Francis Cugler Feb 23 '18 at 03:17
  • This example cannot be compiled in the presented form. The error is related to "no match for operator<< ..."! – Celdor Apr 16 '19 at 14:52
  • @Celdor do you have to appropriate includes; such as ``? – Francis Cugler Apr 16 '19 at 20:57
  • It was a missing include, can’t check it right now but I think it was . I was trying adding ostream, iostream etc. It was hard to find the right one! – Celdor Apr 17 '19 at 03:01
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.

Constantin Geier
  • 303
  • 4
  • 13
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, ";
}
Pratik Patil
  • 3,662
  • 3
  • 31
  • 31
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
Gillespie
  • 5,780
  • 3
  • 32
  • 54
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

Carlo Wood
  • 5,648
  • 2
  • 35
  • 47
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.

arsdever
  • 1,111
  • 1
  • 11
  • 32
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;
}
TheoretiCAL
  • 19,461
  • 8
  • 43
  • 65
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;
}