2016-08-01 39 views
4

我目前正在尝试实现一个函数,该函数将为该函数输入任何其他函数和一组有效的输入值,并返回该函数的结果以及打印执行它需要多长时间。创建可变模板函数来测量和执行其他功能

这里是我到现在为止:

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; 
} 

我尝试的东西像这样运行它:

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

这是一个功能来查找斐波纳契数列的术语。

当我尝试运行它,我得到以下错误:

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

有人可以请给我前进的道路上或如何进行的想法?

+1

看看你传递什么作为第一个参数:'函数& ,矢量&,unsigned long)> fibonacci' - 这看起来不正确。如果你想从'fibonacci'构造一个'std :: function',你不应该把'fibonacci'放在圆括号中,例如'function &,vector &,unsigned long)>(fibonacci) ? – TerraPass

+0

我想你可能会发现std :: bind有趣。 – ZivS

+0

@TerraPass我会试一试。 – soltzu

回答

2

我@ 101010,这是一个基准测试软件的不寻常的方式达成一致意见。

这就是说,这里是具有void返回类型功能也有效的解决方案(在讨论的例子就不会与他们合作):

#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); 
} 

基本的想法是创建一个实例的Check和利用其一生来衡量的时间。

编辑

正如评论提到的,measureAndExecute细化为:

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)...); 
} 
+0

谢谢!我会试一试。很好的使用析构函数。我可以问你为什么要在measureAndExecute正文的第二行中强制检查无效? “(无效)检查;”?最后,为什么与101010提供的链接相比,这种方式是不寻常的? – soltzu

+0

'(void)check'抑制未使用变量的警告。就这样。 :-) – skypjack

+0

好戏,我曾经通过编译器标志压制这些。不再。 – soltzu

4

这是一种非常天真的做基准测试的方法。我建议你看看here更先进的东西。不过,如果你想坚持下去,你应该改为:

template<typename F, typename... Tail> 
auto measureAndExecute(F f, Tail&&... tail) -> typename std::result_of<F(Tail&&...)>::type { 
    std::chrono::high_resolution_clock::time_point time1 = std::chrono::high_resolution_clock::now(); 
    auto res = f(std::forward<Tail>(tail)...); 
    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; 
    return res; 
} 
+0

另外,没有理由使用尾随返回类型。而且,它不适用于具有'void'返回类型的函数。 – skypjack

+0

@101010我看了一下你提供的链接,没有那么不同......他们使用函数而不是方法,但其余的是类似的,至少我没有经验的眼睛。此外,现在没有关于自动返回类型,为我找到持续时间参数的返回类型会节省一些麻烦。我也想说,在他们的代码中,你不能从度量方法返回,但我想这可以通过一个相对简单的修改来解决。 – soltzu

+0

@soltzu看看github链接,那里有一个基准测试工具。您的方法忽略了几个强大的基准测试程序,例如,CPU加热,平均执行时间等。 – 101010