स्कॉट मेयर्स पुस्तक में मुझे सार्वभौमिक जेनेरिक लैम्ब्डा अभिव्यक्ति का एक उदाहरण मिला, जिसका उपयोग फ़ंक्शन निष्पादन समय को मापने के लिए किया जा सकता है। (सी ++ 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;
};
समस्या यह है कि आप केवल एक निष्पादन को मापते हैं ताकि परिणाम बहुत भिन्न हो सकें। एक विश्वसनीय परिणाम प्राप्त करने के लिए आपको बड़ी संख्या में निष्पादन को मापना चाहिए। कोडी में आंद्रेई अलेक्जेंड्रेस्कु व्याख्यान के अनुसार :: गोता 2015 सम्मेलन - लेखन फास्ट कोड I:
मापा समय: tm = t + tq + tn + to to
कहाँ पे:
tm - मापा (मनाया) समय
t - ब्याज का वास्तविक समय
tq - समय परिमाणीकरण शोर द्वारा जोड़ा गया
टीएन - समय शोर के विभिन्न स्रोतों द्वारा जोड़ा जाता है
से - ओवरहेड समय (माप, लूपिंग, कॉलिंग फ़ंक्शन)
व्याख्यान में बाद में उन्होंने जो कहा, उसके अनुसार, आपको अपने परिणाम के रूप में इस निष्पादन की न्यूनतम संख्या लेनी चाहिए। मैं आपको उस व्याख्यान को देखने के लिए प्रोत्साहित करता हूं जिसमें वह बताता है कि क्यों।
इसके अलावा गूगल से एक बहुत अच्छी लाइब्रेरी है - https://github.com/google/benchmark । यह पुस्तकालय उपयोग करने के लिए बहुत ही सरल और शक्तिशाली है। आप YouTube पर Chandler Carruth के कुछ व्याख्यानों की जांच कर सकते हैं जहां वह इस पुस्तकालय का उपयोग कर रहा है। उदाहरण के लिए CppCon 2017: चैंडलर कारुथ "कहीं नहीं जाने वाला तेज़";
उदाहरण उपयोग:
#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
।