简体   繁体   中英

Get average of time spent using std::chrono

I have a function running more than a million times. I want to print out the duration of how long the function takes to run by printing the sum of durations of 10,000 calls to the function.

At the start of each function I have something like this:

int counter = 0;
auto duration_total = 0; //not sure about the type
std::chrono::high_resolution_clock::time_point t1, t2, duration;

t1 = std::chrono::high_resolution_clock::now(); 
Function f(){
  counter++;
}

t2 = std::chrono::high_resolution_clock::now();
duration= std::chrono::duration_cast<std::chrono::nanoseconds>( t2 - t1 ).count();
duration_total += duration;

if(counter %10000 == 0){
      long int average_duration = duration_total/10000;
      duration_total = 0;
      cout << average_duration << "\n";
}

I can't find a way to add durations and then get their average.

You create a clock when you start and one when you stop. When subtracting one clock from another, you get a duration. Divide the duration with the number of iterations.

Example:

#include <chrono>
#include <functional>
#include <iostream>

template<typename T>
auto timeit(size_t iterations, std::function<void()> func_to_test) {
    auto start = std::chrono::high_resolution_clock::now();

    for(size_t i = 0; i < iterations; ++i)
        func_to_test();

    auto end = std::chrono::high_resolution_clock::now();

    return std::chrono::duration_cast<T>(end - start) / iterations;
}

int main() {
    auto dur =
        timeit<std::chrono::microseconds>(10000, [] { system("echo Hello World"); });

    std::cout << dur.count() << " µs\n";
}

If you need to sum up individual runs, keep a duration variable that you add to. I'm reusing the same timeit function, but you can remove the iteration stuff in it if you only want to run it once.

int main() {
    std::chrono::microseconds tot{0};
    size_t iterations = 0;

    for(size_t i = 0; i < 10; ++i) {
        // sum up the total time spent
        tot += timeit<decltype(tot)>(1, [] { system("echo Hello World"); });
        ++iterations;
    }
    // divide with the number of iterations
    std::cout << (tot / iterations).count() << " µs\n";
}

If you look at std::chrono::duration<Rep,Period>::count , you can see that you can use

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

(or something else, eg, unsigned long ), as the return value is

The number of ticks for this duration.

in full:

#include <iostream>
#include <chrono>

int main()
{
    int counter = 0;
    auto duration_total = 0; //not sure about the type
    std::chrono::high_resolution_clock::time_point t1, t2;

    t1 = std::chrono::high_resolution_clock::now(); 

    t2 = std::chrono::high_resolution_clock::now();
    int duration = std::chrono::duration_cast<std::chrono::nanoseconds>( t2 - t1 ).count();
    duration_total += duration;

    if(counter %10000 == 0){
          long int average_duration = duration_total/10000;
          duration_total = 0;
          std::cout << average_duration << "\n";
    }
}

See it in Coliru .

First, the type here is int:

auto duration_total = 0;

You should do something similar to it:

auto t1 = std::chrono::steady_clock::now();
//do some work
auto t2 = std::chrono::steady_clock::now();
double duration_in_seconds = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1).count();

Note that I'm casting the duration to double. Then you can use the duration value more freely.

If you prefer nanoseconds:

double duration_in_nanoseconds =  std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM