northerner
northerner

Reputation: 794

How to add times taken to execute a function inside of a loop?

I have two implementations of a function and would like to see which is faster. Call them foo1() and foo2(). I have a set of test cases I would like to run against both of them. The tests cases are stored in an array and I don't want to include the time spent accessing the array. Here is my code. It doesn't compile on duration += std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ) with error message error: no match for 'operator<<' (operand types are 'std::basic_ostream<char>' and 'std::chrono::microseconds' {aka 'std::chrono::duration<long long int, std::ratio<1, 1000000> >'}) 52 | std::cout << "duration: " << duration << std::endl;.

Code:

/*[first argument, second argument, correct result]*/
 int inout[5][3] = {
    {10, 4, 5},
    {21, 4, 6},
    {22, 4, 7},
    {50, 5, 19},
    {100, 5, 7},
    //just example, real one is longer


};

std::chrono::microseconds duration = std::chrono::microseconds::zero();
for(auto& i : inout)
{
    auto t1 = std::chrono::high_resolution_clock::now();
    foo1(i[0], i[1]);
    auto t2 = std::chrono::high_resolution_clock::now();
    duration += std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();//this won't compile
}
std::cout << "duration of foo1(): " << duration << std::endl;

duration = std::chrono::microseconds::zero();
for(auto& i : inout)
{
    auto t1 = std::chrono::high_resolution_clock::now();
    foo2(i[0], i[1]);
    auto t2 = std::chrono::high_resolution_clock::now();
    duration += std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();//this won't compile
}
std::cout << "duration of foo2(): " << duration << std::endl;

Any suggestions on anything here? I was thinking it's more meaningful to test the speed for cache misses so should the calls to foo1() and foo2() be interlaced? OTOH the goal is to see which is faster and both would benefit from the cache, however the bigger one would likely have more cache misses. Also out of curiosity what is the type on auto& i in the foreach loop?

Upvotes: 0

Views: 133

Answers (2)

overseas
overseas

Reputation: 1731

This is how it could be:

std::chrono::microseconds duration = std::chrono::microseconds::zero();
for (auto &i : inout) {
  auto t1 = std::chrono::high_resolution_clock::now();
  // f1()
  auto t2 = std::chrono::high_resolution_clock::now();
  duration += std::chrono::duration_cast<std::chrono::microseconds>(
      t2 - t1);
}
std::cout << "duration of foo1(): " << duration.count() << std::endl;

duration = std::chrono::microseconds::zero();
for (auto &i : inout) {
  auto t1 = std::chrono::high_resolution_clock::now();
  // f2()
  auto t2 = std::chrono::high_resolution_clock::now();
  duration += std::chrono::duration_cast<std::chrono::microseconds>(
      t2 - t1);
}
std::cout << "duration of foo2(): " << duration.count() << std::endl;
}

Some explanation: If you have an error message like

<source>:23:14: error: no match for 'operator+=' (operand types are 'std::chrono::microseconds' {aka 'std::chrono::duration<long int, std::ratio<1, 1000000> >'} and 'std::chrono::duration<long int, std::ratio<1, 1000000> >::rep' {aka 'long int'})

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

You can see that there is no operator for microseconds and long int. So you can go to the documentation and see what operators are there for duration and you will find https://en.cppreference.com/w/cpp/chrono/duration/operator_arith3.

You see that you have to pass another duration, so you should not call count() there.

Upvotes: 3

D.Malim
D.Malim

Reputation: 116

If I guess you could have used time.h from C library that can help you achieve same thing. Only if you don't want to use chrono class.

Here is what I would suggest.

#include <time.h>
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
using namespace std;


  void foo1(){

    sleep(5);
  }
  int main(){

    time_t StarTime, EndTime;


    memset( &StarTime, 0x00, sizeof(StarTime));
    memset( &EndTime, 0x00, sizeof(EndTime));

    time(&StarTime);


    foo1();


    time(&EndTime);
    double secs = difftime(EndTime, StarTime);
    double mins =0.0;
    if(secs >= 60){
            mins = (secs/60);
            printf("Total Time:%-10.5f MINS\n",mins);
    }else{
            printf("Total Time:%-10.5f SECS\n",secs);
    }
    return 0;

  }

This is the output observed.

Total Time:5.00000    SECS

As you can see here I got the time taken by foo1() to complete you can do that for foo2() also than you can compare them for benchmarking.

Upvotes: 0

Related Questions