soltzu - 1 year ago 52

C++ Question

I am currently trying to implement a function that will take as input any other function and a valid set of input values for that function and return the result of the function as well as printing how long it took to execute it.

Here is what I have until now:

`template<typename T, typename... Tail>`

T measureAndExecute(const function<T(Tail...)> f, Tail... tail) {

high_resolution_clock::time_point time1 = high_resolution_clock::now();

T res = f(tail...);

high_resolution_clock::time_point time2 = high_resolution_clock::now();

auto duration = duration_cast<milliseconds>(time2 - time1).count();

cout << duration << " milliseconds" << endl;

return res;

}

And I try to run it with something like this:

`int res = measureAndExecute(function<int(vector<int>&, vector<bool>&, unsigned long)> fibonacci, terms, calculated, n-1);`

Which is a function to find a term in the Fibonacci series.

When I try to run it I get the following error:

`error: expected '(' for function-style cast or type construction`

Can somebody please give me a way forward or ideas on how to proceed?

Answer Source

I agree with @101010 that this is a unusual way of benchmarking a software.

That said, here is a solution that works also with functions having`void`

return type (the example in the question wouldn't have worked with them):

```
#include<type_traits>
#include<iostream>
struct Check {
Check(): time1{std::chrono::high_resolution_clock::now()} {}
~Check() {
std::chrono::high_resolution_clock::time_point time2 = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(time2 - time1).count();
std::cout << duration << " milliseconds" << std::endl;
}
std::chrono::high_resolution_clock::time_point time1;
};
template<typename F, typename... Tail>
typename std::result_of<F(Tail&&...)>::type measureAndExecute(F f, Tail&&... tail) {
Check check;
(void)check;
return f(std::forward<Tail>(tail)...);
}
int f(int i) { return i; }
void g() { }
int main() {
measureAndExecute(f, 42);
measureAndExecute(g);
}
```

The basic idea is to create an instance of `Check`

and exploit its lifetime to measure the time.

**EDIT**

As mentioned in the comments, a refinement of `measureAndExecute`

would be:

```
template<typename F, typename... Tail>
typename std::result_of<F&&(Tail&&...)>::type measureAndExecute(F &&f, Tail&&... tail) {
Check check;
(void)check;
return std::forward<F>(f)(std::forward<Tail>(tail)...);
}
```