Scott Meyers kitabında, fonksiyon yürütme süresini ölçmek için kullanılabilecek evrensel bir genel lambda ifadesi örneği buldum. (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;
};
Sorun, yalnızca bir yürütmeyi ölçmenizdir, bu nedenle sonuçlar çok farklı olabilir. Güvenilir bir sonuç elde etmek için çok sayıda yürütmeyi ölçmelisiniz. Andrei Alexandrescu'nun code :: dive 2015 konferansındaki konuşmasına göre - Hızlı Kod Yazma I:
Ölçülen zaman: tm = t + tq + tn + to
nerede:
tm - ölçülen (gözlemlenen) zaman
t - gerçek ilgi zamanı
tq - niceleme gürültüsü tarafından eklenen zaman
tn - çeşitli gürültü kaynakları tarafından eklenen zaman
to - genel gider süresi (ölçüm, döngü, fonksiyon çağırma)
Daha sonra konferansta söylediklerine göre, sonuç olarak bu kadar çok sayıda infazı asgari düzeyde almalısınız. Nedenini açıkladığı derse bakmanızı tavsiye ederim.
Ayrıca google'dan çok iyi bir kitaplık var - https://github.com/google/benchmark . Bu kitaplığın kullanımı çok basit ve güçlüdür. Chandler Carruth'un bu kütüphaneyi pratikte kullandığı youtube'daki bazı derslerine göz atabilirsiniz. Örneğin CppCon 2017: Chandler Carruth "Hiçbir Yere Daha Hızlı Gitmiyor";
Örnek kullanım:
#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;
}
DÜZENLEME: Elbette, derleyicinizin bir şeyi optimize edip edemeyeceğini her zaman hatırlamanız gerekir. Perf gibi araçlar bu gibi durumlarda faydalı olabilir.
clock_gettime
.. gcc diğer saatleri şu şekilde tanımlar:typedef system_clock steady_clock; typedef system_clock high_resolution_clock;
Windows'ta kullanınQueryPerformanceCounter
.