Scott Meyersの本で、関数の実行時間を測定するために使用できる汎用の汎用ラムダ式の例を見つけました。(C ++ 14)
auto timeFuncInvocation =
[](auto&& func, auto&&... params) {
// get time before function invocation
const auto& start = std::chrono::high_resolution_clock::now();
// function invocation using perfect forwarding
std::forward<decltype(func)>(func)(std::forward<decltype(params)>(params)...);
// get time after function invocation
const auto& stop = std::chrono::high_resolution_clock::now();
return stop - start;
};
問題は、1つの実行のみを測定するため、結果が大きく異なる可能性があることです。信頼できる結果を得るには、多数の実行を測定する必要があります。code :: dive 2015カンファレンスでのAndrei Alexandrescuの講演によると-高速コードの作成I:
測定時間:tm = t + tq + tn + to
どこ:
tm-測定された(観測された)時間
t-関心のある実際の時間
tq-量子化ノイズによって追加された時間
tn-さまざまなノイズ源によって追加された時間
to-オーバーヘッド時間(測定、ループ、関数の呼び出し)
彼が講義の後半で言ったように、あなたは結果としてこの大量の実行の最小値を取るべきです。彼がその理由を説明している講義をご覧になることをお勧めします。
また、グーグルからの非常に良いライブラリがあります-https://github.com/google/benchmark。このライブラリは非常に使いやすく、強力です。Chandler Carruthの講義をyoutubeでチェックアウトして、実際にこのライブラリを使用しています。たとえば、CppCon 2017:Chandler Carruthが「どこにも行かない」;
使用例:
#include <iostream>
#include <chrono>
#include <vector>
auto timeFuncInvocation =
[](auto&& func, auto&&... params) {
// get time before function invocation
const auto& start = high_resolution_clock::now();
// function invocation using perfect forwarding
for(auto i = 0; i < 100000/*largeNumber*/; ++i) {
std::forward<decltype(func)>(func)(std::forward<decltype(params)>(params)...);
}
// get time after function invocation
const auto& stop = high_resolution_clock::now();
return (stop - start)/100000/*largeNumber*/;
};
void f(std::vector<int>& vec) {
vec.push_back(1);
}
void f2(std::vector<int>& vec) {
vec.emplace_back(1);
}
int main()
{
std::vector<int> vec;
std::vector<int> vec2;
std::cout << timeFuncInvocation(f, vec).count() << std::endl;
std::cout << timeFuncInvocation(f2, vec2).count() << std::endl;
std::vector<int> vec3;
vec3.reserve(100000);
std::vector<int> vec4;
vec4.reserve(100000);
std::cout << timeFuncInvocation(f, vec3).count() << std::endl;
std::cout << timeFuncInvocation(f2, vec4).count() << std::endl;
return 0;
}
編集:もちろん、コンパイラは何かを最適化できるかどうかを常に覚えておく必要があります。そのような場合、perfなどのツールが役立ちます。
clock_gettime
.. gccは他のクロックを次のようtypedef system_clock steady_clock; typedef system_clock high_resolution_clock;
に定義します。Windowsでは、を使用しますQueryPerformanceCounter
。