Trong cuốn sách Scott Meyers tôi đã tìm thấy một ví dụ về biểu thức lambda chung có thể được sử dụng để đo thời gian thực hiện chức năng. (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;
};
Vấn đề là bạn chỉ đo một lần thực hiện nên kết quả có thể rất khác nhau. Để có được kết quả đáng tin cậy, bạn nên đo một số lượng lớn thực hiện. Theo bài giảng của Andrei Alexandrescu tại code :: hội nghị dive 2015 - Viết mã nhanh I:
Thời gian đo: tm = t + tq + tn + to
Ở đâu:
tm - thời gian đo (quan sát)
t - thời gian thực sự quan tâm
tq - thời gian được thêm bởi tiếng ồn lượng tử hóa
tn - thời gian được thêm vào bởi các nguồn tiếng ồn khác nhau
đến - thời gian trên không (đo, lặp, chức năng gọi)
Theo những gì ông nói sau trong bài giảng, bạn nên lấy tối thiểu số lượng lớn thực hiện này làm kết quả của bạn. Tôi khuyến khích bạn nhìn vào bài giảng mà anh ấy giải thích tại sao.
Ngoài ra còn có một thư viện rất tốt từ google - https://github.com/google/benchmark . Thư viện này rất đơn giản để sử dụng và mạnh mẽ. Bạn có thể kiểm tra một số bài giảng của Chandler Carruth trên youtube nơi anh ấy đang sử dụng thư viện này trong thực tế. Ví dụ: CppCon 2017: Chandler Carruth Di Đi đâu nhanh hơn;
Ví dụ sử dụng:
#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;
}
EDIT: Tất nhiên bạn luôn cần nhớ rằng trình biên dịch của bạn có thể tối ưu hóa một cái gì đó hay không. Các công cụ như perf có thể hữu ích trong những trường hợp như vậy.
clock_gettime
.. gcc định nghĩa các đồng hồ khác là:typedef system_clock steady_clock; typedef system_clock high_resolution_clock;
trên Windows, sử dụngQueryPerformanceCounter
.