2016-08-01 40 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