C ++ में किसी फ़ंक्शन का निष्पादन समय मापना


138

मैं यह जानना चाहता हूं कि लिनक्स पर निष्पादित करने के लिए मेरे C ++ प्रोग्राम में एक निश्चित फ़ंक्शन को कितना समय लगता है । बाद में, मैं एक गति तुलना करना चाहता हूं। मैंने कई बार समारोह देखा लेकिन इसे बढ़ावा देने के साथ समाप्त हुआ। Chrono:

process_user_cpu_clock, captures user-CPU time spent by the current process

अब, मैं स्पष्ट नहीं हूं कि अगर मैं उपरोक्त फ़ंक्शन का उपयोग करता हूं, तो क्या मुझे केवल वही समय मिलेगा जो सीपीयू ने उस फ़ंक्शन पर खर्च किया है?

दूसरे, मुझे उपरोक्त फ़ंक्शन का उपयोग करने का कोई उदाहरण नहीं मिला। क्या कोई भी कृपया मेरी मदद कर सकता है कि उपरोक्त फ़ंक्शन का उपयोग कैसे करें?

पुनश्च: अभी, मैं std::chrono::system_clock::now()सेकंड में समय प्राप्त करने के लिए उपयोग कर रहा हूं लेकिन यह मुझे हर बार अलग-अलग सीपीयू लोड के कारण अलग-अलग परिणाम देता है।


2
Linux उपयोग के लिए: clock_gettime.. gcc अन्य घड़ियों को परिभाषित करता है जैसे: typedef system_clock steady_clock; typedef system_clock high_resolution_clock;Windows पर, उपयोग करें QueryPerformanceCounter
ब्रैंडन

इस सवाल का डुप्लिकेट नहीं है यह एक या परिदृश्यों समाधान अलग कर सकता हूँ?
उत्तरवासी

मेरे पास एक फ़ंक्शन के दो कार्यान्वयन हैं और यह खोजना चाहेंगे कि कौन सा बेहतर प्रदर्शन करता है।
उत्तरवासी

बहुत महत्वपूर्ण: सुनिश्चित करें कि आप अनुकूलन सक्षम करें । अन-ऑप्टिमाइज़्ड कोड में सामान्य अनुकूलित कोड की तुलना में अलग - अलग अड़चनें होती हैं, और आपको कुछ भी सार्थक नहीं बताता है। अंतिम कार्य के लिए C लूप ऑप्टिमाइज़ेशन मदद (कंपाइलर ऑप्टिमाइज़ेशन अक्षम के साथ) । और सामान्य रूप से माइक्रोबेनमार्किंग में कई नुकसान होते हैं, विशेष रूप से सीपीयू-फ्रीक्वेंसी और पेज दोष के लिए पहले वार्म-अप लूप करने में विफलता: प्रदर्शन मूल्यांकन का मुहावरेदार तरीका? । और यह जवाब
पीटर कॉर्ड्स

यह भी देखें कि आप किसी फ़ंक्शन के प्रदर्शन को कैसे मानेंगे? Google बेंचमार्क के लिए जो अपने स्वयं के माइक्रोबेनमार्क को रोल करने के कई नुकसानों से बचता है। इसके अलावा सिंपल फॉरवर्ड () लूप बेंचमार्क किसी भी लूप के साथ उसी समय से अधिक समय लेता है जब बेंचमार्क लूप्स के साथ ऑप्टिमाइजेशन कैसे इंटरैक्ट करता है, और इसके बारे में क्या करना है।
पीटर कॉर्डेस

जवाबों:


264

यह C ++ 11 में एक बहुत ही आसान उपयोग विधि है। आपको हेडर std::chrono::high_resolution_clockसे उपयोग करना होगा <chrono>

इसका उपयोग ऐसे करें:

#include <iostream>
#include <chrono>

void function()
{
    long long number = 0;

    for( long long i = 0; i != 2000000; ++i )
    {
       number += 5;
    }
}

int main()
{
    auto t1 = std::chrono::high_resolution_clock::now();
    function();
    auto t2 = std::chrono::high_resolution_clock::now();

    auto duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();

    std::cout << duration;
    return 0;
}

यह फ़ंक्शन की अवधि को मापेगा।

नोट: आपको हमेशा किसी फ़ंक्शन के लिए समान समय नहीं मिलेगा। ऐसा इसलिए है क्योंकि आपके मशीन का सीपीयू आपके कंप्यूटर पर चलने वाली अन्य प्रक्रियाओं द्वारा कम या ज्यादा इस्तेमाल किया जा सकता है, जैसे कि जब आप गणित अभ्यास को हल करते हैं तो आपका दिमाग कम या ज्यादा केंद्रित हो सकता है। मानव मन में, हम एक गणित समस्या का हल याद कर सकते हैं, लेकिन एक कंप्यूटर के लिए एक ही प्रक्रिया हमेशा कुछ नया होगा; इस प्रकार, जैसा कि मैंने कहा, आपको हमेशा समान परिणाम नहीं मिलेगा!


जब मैं इस फ़ंक्शन का उपयोग करता हूं, तो पहले रन पर इसने मुझे 118440535 माइक्रोसेकंड दिए और उसी फ़ंक्शन के दूसरे भाग में इसने मुझे 83221031 माइक्रोसेकंड दिए। जब मैं केवल उस फ़ंक्शन की अवधि को माप रहा हूं तो क्या दो समय माप बराबर नहीं होना चाहिए?
Xara

1
नहीं। आपके कंप्यूटर का प्रोसेसर कम या ज्यादा इस्तेमाल किया जा सकता है। high_resolution_clockआप शारीरिक और वास्तविक समय अपने कार्य को चलाने के लिए ले जाता है कि दे देंगे। इसलिए, आपके पहले रन में, आपके CPU को अगले रन की तुलना में कम इस्तेमाल किया जा रहा था। "इस्तेमाल किया" से मेरा मतलब है कि सीपीयू क्या अन्य एप्लिकेशन काम करता है।
विक्टर

1
हां, यदि आपको समय के औसत की आवश्यकता है, तो इसे प्राप्त करने का एक अच्छा तरीका है। तीन रन लें, और औसत की गणना करें।
विक्टर

3
क्या आप सामान्य रूप से "नाम स्थान का उपयोग किए बिना" कोड पोस्ट कर सकते हैं। यह देखना आसान बनाता है कि कहां से आता है।
स्नोमैन

1
यह एक नहीं होना चाहिए steady_clock? क्या यह संभव नहीं है कि high_resolution_clockएक गैर-मोनोटोनिक घड़ी हो?
गिलेस्पी

15

यहाँ एक फ़ंक्शन है जो तर्क के रूप में पारित किसी भी फ़ंक्शन के निष्पादन समय को मापेगा:

#include <chrono>
#include <utility>

typedef std::chrono::high_resolution_clock::time_point TimeVar;

#define duration(a) std::chrono::duration_cast<std::chrono::nanoseconds>(a).count()
#define timeNow() std::chrono::high_resolution_clock::now()

template<typename F, typename... Args>
double funcTime(F func, Args&&... args){
    TimeVar t1=timeNow();
    func(std::forward<Args>(args)...);
    return duration(timeNow()-t1);
}

उदाहरण उपयोग:

#include <iostream>
#include <algorithm>

typedef std::string String;

//first test function doing something
int countCharInString(String s, char delim){
    int count=0;
    String::size_type pos = s.find_first_of(delim);
    while ((pos = s.find_first_of(delim, pos)) != String::npos){
        count++;pos++;
    }
    return count;
}

//second test function doing the same thing in different way
int countWithAlgorithm(String s, char delim){
    return std::count(s.begin(),s.end(),delim);
}


int main(){
    std::cout<<"norm: "<<funcTime(countCharInString,"precision=10",'=')<<"\n";
    std::cout<<"algo: "<<funcTime(countWithAlgorithm,"precision=10",'=');
    return 0;
}

आउटपुट:

norm: 15555
algo: 2976

2
@ RestlessC0bra: यह एंप्लायमेंट डिफाइन है, (दीवार घड़ी), या तीसरी स्वतंत्र घड़ी high_resolution_clockका एक अन्य नाम हो सकता है । विवरण यहाँ देखें । सीपीयू घड़ी के लिए, इस्तेमाल किया जा सकता हैsystem_clocksteady_clockstd::clock
जाहिद

2
दो मैक्रोज़ और एक वैश्विक टाइप-बीफ़ - जिनमें से कोई भी सुरक्षित नहीं है, एक ही की -ट्रोकेक - निश्चित रूप से कुछ भी नहीं है जिसे मैं सुरुचिपूर्ण कहूँगा। इसके अलावा, किसी फंक्शन ऑब्जेक्ट को पास करना और तर्कों को अलग-अलग अग्रेषित करना एक ओवरकिल का एक सा है (और अतिभारित कार्यों के मामले में भी असुविधाजनक), जब आपको केवल एक लैम्बडा में समयबद्ध कोड डालने की आवश्यकता हो सकती है। लेकिन ठीक है, जब तक कि तर्कों को पारित करना वैकल्पिक है।
माइक एमबी

2
और मैक्रों के नामकरण के बारे में प्रत्येक दिशानिर्देश का उल्लंघन करने का यह एक औचित्य है? आप उन्हें उपसर्ग नहीं देते हैं, आप बड़े अक्षरों का उपयोग नहीं करते हैं, आप एक बहुत ही सामान्य नाम चुनते हैं, जिसमें कुछ स्थानीय प्रतीक और सबसे अधिक से टकराने की संभावना है: आप एक मैक्रो का उपयोग क्यों कर रहे हैं (बजाय एक फ़ंक्शन के )? और जब हम इस पर हैं: आप पहले स्थान पर नैनोसेकंड का प्रतिनिधित्व करने वाले दोहरी अवधि के रूप में क्यों लौट रहे हैं? हमें शायद सहमत होना चाहिए कि हम असहमत हैं। मेरी मूल राय है: "यह वह नहीं है जिसे मैं सुरुचिपूर्ण कोड कहूंगा"।
मिकएमबी

1
समस्या यह है कि वे अनियंत्रित हैं। मैं किस बारे में चिंतित हूं कि इस तरह के मैक्रोज़ हेडर फ़ाइल में समाप्त हो जाते हैं, जो कि (शायद एक पुस्तकालय के हिस्से के रूप में अप्रत्यक्ष रूप से) मेरे कोड में शामिल हैं। यदि आप चाहते हैं कि क्या हो मैक्रोज़ के लिए सामान्य नामों का उपयोग किया जाता है, windows.hएक गैर-तुच्छ सी ++ परियोजना में शामिल हैं। assertसबसे पहले के बारे में : "quod licet iovi non licet bovi";)। दूसरा, मानक पुस्तकालय (कभी-कभी दशकों से डेटिंग) में सभी निर्णय वास्तव में आधुनिक मानकों द्वारा एक अच्छा विचार नहीं माना जाता है। वहाँ एक कारण है, क्यों सी ++ मॉड्यूल डिजाइनर बहुत कोशिश करते हैं कि डिफ़ॉल्ट रूप से मैक्रोज़ निर्यात न करें।
माइकएम

2
@ जाहिद: ​​धन्यवाद। उस स्थिति में मेरी टिप्पणियों को शून्य और अशक्त मानिए।
माइक एमबी

9

एक कार्य निष्पादन समय खोजने के लिए सरल कार्यक्रम।

#include <iostream>
#include <ctime> // time_t
#include <cstdio>

void function()
{
     for(long int i=0;i<1000000000;i++)
     {
        // do nothing
     }
}

int main()
{

time_t begin,end; // time_t is a datatype to store time values.

time (&begin); // note time before execution
function();
time (&end); // note time after execution

double difference = difftime (end,begin);
printf ("time taken for function() %.2lf seconds.\n", difference );

return 0;
}

6
यह बहुत गलत है, केवल कुछ सेकंड दिखाता है, लेकिन कोई मिलीसेकंड नहीं
उपयोगकर्ता 25

7

स्कॉट मेयर्स पुस्तक में मुझे सार्वभौमिक जेनेरिक लैम्ब्डा अभिव्यक्ति का एक उदाहरण मिला, जिसका उपयोग फ़ंक्शन निष्पादन समय को मापने के लिए किया जा सकता है। (सी ++ 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 जैसे उपकरण उपयोगी हो सकते हैं।


दिलचस्प है - एक फ़ंक्शन टेम्पलेट पर यहां लैम्बडा का उपयोग करने का क्या लाभ है?
user48956

1
मुख्य अंतर यह होगा कि यह एक कॉल करने योग्य वस्तु है, लेकिन वास्तव में आप वैरेडिक टेम्प्लेट और std :: result_oftt के साथ कुछ समान प्राप्त कर सकते हैं।
क्रिज़ीस्तोफ़ सोमरफेल्ड

@KrzysztofSommerfeld फ़ंक्शन विधि के लिए इसे कैसे करें, जब मैं टाइमिंग पास करता हूं (Object.Method1) यह त्रुटि "गैर-मानक सिंटैक्स वापस करता है, तो सदस्य को पॉइंटर बनाने के लिए '&' का उपयोग करें"
RobaAtTech

timeFuncInvocation ([& objectName] (ऑटो && ... args) {objectName.methodName (std :: आगे <घोषणापत्र (args)> (args) ...);}; arg1, arg2, ...); या ommit और objectName से पहले साइन इन करें (तब आपके पास ऑब्जेक्ट की एक प्रति होगी)
Krzysztof Sommerfeld

4

पुराने C ++ या C के लिए आसान तरीका:

#include <time.h> // includes clock_t and CLOCKS_PER_SEC

int main() {

    clock_t start, end;

    start = clock();
    // ...code to measure...
    end = clock();

    double duration_sec = double(end-start)/CLOCKS_PER_SEC;
    return 0;
}

सेकंड में समय सटीक है 1.0/CLOCKS_PER_SEC


1
यह पोर्टेबल नहीं है। यह लिनक्स पर प्रोसेसर समय और विंडोज पर घड़ी का समय मापता है।
बगसक्शेर

2
  • C ++ 11 में विधि का उपयोग करना बहुत आसान है।
  • हम हेडर से std :: chrono :: high_resolution_clock का उपयोग कर सकते हैं
  • हम विधि निष्पादन समय को बहुत पठनीय रूप में मुद्रित करने के लिए एक विधि लिख सकते हैं।

उदाहरण के लिए, 1 और 100 मिलियन के बीच सभी प्रमुख संख्याओं को खोजने के लिए, लगभग 1 मिनट और 40 सेकंड लगते हैं। इसलिए निष्पादन का समय इस प्रकार है:

Execution Time: 1 Minutes, 40 Seconds, 715 MicroSeconds, 715000 NanoSeconds

कोड यहाँ है:

#include <iostream>
#include <chrono>

using namespace std;
using namespace std::chrono;

typedef high_resolution_clock Clock;
typedef Clock::time_point ClockTime;

void findPrime(long n, string file);
void printExecutionTime(ClockTime start_time, ClockTime end_time);

int main()
{
    long n = long(1E+8);  // N = 100 million

    ClockTime start_time = Clock::now();

    // Write all the prime numbers from 1 to N to the file "prime.txt"
    findPrime(n, "C:\\prime.txt"); 

    ClockTime end_time = Clock::now();

    printExecutionTime(start_time, end_time);
}

void printExecutionTime(ClockTime start_time, ClockTime end_time)
{
    auto execution_time_ns = duration_cast<nanoseconds>(end_time - start_time).count();
    auto execution_time_ms = duration_cast<microseconds>(end_time - start_time).count();
    auto execution_time_sec = duration_cast<seconds>(end_time - start_time).count();
    auto execution_time_min = duration_cast<minutes>(end_time - start_time).count();
    auto execution_time_hour = duration_cast<hours>(end_time - start_time).count();

    cout << "\nExecution Time: ";
    if(execution_time_hour > 0)
    cout << "" << execution_time_hour << " Hours, ";
    if(execution_time_min > 0)
    cout << "" << execution_time_min % 60 << " Minutes, ";
    if(execution_time_sec > 0)
    cout << "" << execution_time_sec % 60 << " Seconds, ";
    if(execution_time_ms > 0)
    cout << "" << execution_time_ms % long(1E+3) << " MicroSeconds, ";
    if(execution_time_ns > 0)
    cout << "" << execution_time_ns % long(1E+6) << " NanoSeconds, ";
}

0

किसी फ़ंक्शन या किसी कोड ब्लॉक के बीता समय को मापने के लिए यहां एक उत्कृष्ट शीर्षलेख केवल वर्ग टेम्पलेट है:

#ifndef EXECUTION_TIMER_H
#define EXECUTION_TIMER_H

template<class Resolution = std::chrono::milliseconds>
class ExecutionTimer {
public:
    using Clock = std::conditional_t<std::chrono::high_resolution_clock::is_steady,
                                     std::chrono::high_resolution_clock,
                                     std::chrono::steady_clock>;
private:
    const Clock::time_point mStart = Clock::now();

public:
    ExecutionTimer() = default;
    ~ExecutionTimer() {
        const auto end = Clock::now();
        std::ostringstream strStream;
        strStream << "Destructor Elapsed: "
                  << std::chrono::duration_cast<Resolution>( end - mStart ).count()
                  << std::endl;
        std::cout << strStream.str() << std::endl;
    }    

    inline void stop() {
        const auto end = Clock::now();
        std::ostringstream strStream;
        strStream << "Stop Elapsed: "
                  << std::chrono::duration_cast<Resolution>(end - mStart).count()
                  << std::endl;
        std::cout << strStream.str() << std::endl;
    }

}; // ExecutionTimer

#endif // EXECUTION_TIMER_H

इसके कुछ उपयोग इस प्रकार हैं:

int main() {
    { // empty scope to display ExecutionTimer's destructor's message
         // displayed in milliseconds
         ExecutionTimer<std::chrono::milliseconds> timer;

         // function or code block here

         timer.stop();

    } 

    { // same as above
        ExecutionTimer<std::chrono::microseconds> timer;

        // code block here...

        timer.stop();
    }

    {  // same as above
       ExecutionTimer<std::chrono::nanoseconds> timer;

       // code block here...

       timer.stop();

    }

    {  // same as above
       ExecutionTimer<std::chrono::seconds> timer;

       // code block here...

       timer.stop();

    }              

    return 0;
}

चूंकि क्लास एक टेम्प्लेट है, हम वास्तविक को आसानी से निर्दिष्ट कर सकते हैं कि हम अपना समय कैसे मापना और प्रदर्शित करना चाहते हैं। यह बेंच मार्किंग करने के लिए एक बहुत ही उपयोगी उपयोगिता वर्ग टेम्पलेट है और इसका उपयोग करना बहुत आसान है।


व्यक्तिगत रूप से, stop()सदस्य फ़ंक्शन की आवश्यकता नहीं है क्योंकि विध्वंसक आपके लिए टाइमर बंद कर देता है।
केसी

@ कैसी वर्ग के डिजाइन को स्टॉप फ़ंक्शन की आवश्यकता नहीं है, हालांकि यह एक विशिष्ट कारण के लिए है। test codeटाइमर शुरू करने से पहले ऑब्जेक्ट बनाते समय डिफ़ॉल्ट निर्माण । फिर आपके बाद test codeआप स्पष्ट रूप से टाइमर ऑब्जेक्ट का उपयोग करें और इसकी स्टॉप विधि को कॉल करें। जब आप stopटाइमर चाहते हैं, तो आपको इसे मैन्युअल रूप से लागू करना होगा । वर्ग कोई भी पैरामीटर नहीं लेता है। इसके अलावा अगर आपने इस वर्ग का उपयोग किया है जैसा कि मैंने दिखाया है कि आप देखेंगे कि कॉल obj.stopऔर इसके बीच कम से कम समय बीत चुका है destructor
फ्रांसिस कुगलर

@ कैसी ... यह एक ही दायरे में कई टाइमर ऑब्जेक्ट्स को रखने की अनुमति देता है, ऐसा नहीं है कि किसी को वास्तव में इसकी आवश्यकता होगी, लेकिन सिर्फ एक और व्यवहार्य विकल्प।
फ्रांसिस कुगलर

इस उदाहरण को प्रस्तुत रूप में संकलित नहीं किया जा सकता है। त्रुटि "ऑपरेटर के लिए कोई मिलान नहीं <<" ... से संबंधित है
Celdor

@Celdor क्या आपको उचित शामिल करना है; जैसे कि <chrono>?
फ्रांसिस कुगलर

0

मैं steady_clockइसके विपरीत मोनोटोनिक होने के लिए निर्देशित है, जिसका उपयोग करने की सलाह देता हूं high_resolution_clock

#include <iostream>
#include <chrono>

using namespace std;

unsigned int stopwatch()
{
    static auto start_time = chrono::steady_clock::now();

    auto end_time = chrono::steady_clock::now();
    auto delta    = chrono::duration_cast<chrono::microseconds>(end_time - start_time);

    start_time = end_time;

    return delta.count();
}

int main() {
  stopwatch(); //Start stopwatch
  std::cout << "Hello World!\n";
  cout << stopwatch() << endl; //Time to execute last line
  for (int i=0; i<1000000; i++)
      string s = "ASDFAD";
  cout << stopwatch() << endl; //Time to execute for loop
}

आउटपुट:

Hello World!
62
163514

0

आपके पास एक साधारण वर्ग हो सकता है जिसका उपयोग इस तरह के माप के लिए किया जा सकता है।

class duration_printer {
public:
    duration_printer() : __start(std::chrono::high_resolution_clock::now()) {}
    ~duration_printer() {
        using namespace std::chrono;
        high_resolution_clock::time_point end = high_resolution_clock::now();
        duration<double> dur = duration_cast<duration<double>>(end - __start);
        std::cout << dur.count() << " seconds" << std::endl;
    }
private:
    std::chrono::high_resolution_clock::time_point __start;
};

उस फ़ंक्शन की शुरुआत में आपके फ़ंक्शन में एक ऑब्जेक्ट बनाने के लिए केवल एक चीज की आवश्यकता होती है

void veryLongExecutingFunction() {
    duration_calculator dc;
    for(int i = 0; i < 100000; ++i) std::cout << "Hello world" << std::endl;
}

int main() {
    veryLongExecutingFunction();
    return 0;
}

और बस। अपनी आवश्यकताओं को पूरा करने के लिए कक्षा को संशोधित किया जा सकता है।


0

चूँकि प्रदान किए गए उत्तरों में से कोई भी बहुत सटीक नहीं है या पुन: प्रस्तुत करने योग्य परिणाम नहीं देता है, इसलिए मैंने अपने कोड में एक लिंक जोड़ने का फैसला किया है जिसमें सब-नैनो-सेकेंड सटीक और वैज्ञानिक आँकड़े हैं।

ध्यान दें कि यह केवल उस कोड को मापने के लिए काम करेगा जो चलाने के लिए (बहुत) कम समय (उर्फ, कुछ घड़ी साइकिल कुछ हजार तक) लेता है: यदि वे इतने लंबे समय तक चलते हैं कि वे कुछ-बाधित होने की संभावना है , तो यह स्पष्ट रूप से एक प्रतिलिपि प्रस्तुत करने योग्य और सटीक परिणाम देने के लिए संभव नहीं है; जिसका नतीजा यह है कि माप कभी खत्म नहीं होता है: अर्थात्, यह तब तक मापना जारी रखता है जब तक कि यह सांख्यिकीय रूप से 99.9% न हो, इसका सही उत्तर है कि मशीन पर कभी ऐसा नहीं होता है जिसमें कोड चलने में बहुत समय लगने पर अन्य प्रक्रियाएं चलती हैं।

https://github.com/CarloWood/cwds/blob/master/benchmark.h#L40


0

यदि आप सुरक्षित समय और कोड की लाइनें चाहते हैं, तो आप फ़ंक्शन निष्पादन समय को एक पंक्ति मैक्रो को माप सकते हैं:

a) पहले से ही सुझाए गए समय को मापने वाला वर्ग लागू करें (यहाँ Android के लिए मेरा कार्यान्वयन है):

class MeasureExecutionTime{
private:
    const std::chrono::steady_clock::time_point begin;
    const std::string caller;
public:
    MeasureExecutionTime(const std::string& caller):caller(caller),begin(std::chrono::steady_clock::now()){}
    ~MeasureExecutionTime(){
        const auto duration=std::chrono::steady_clock::now()-begin;
        LOGD("ExecutionTime")<<"For "<<caller<<" is "<<std::chrono::duration_cast<std::chrono::milliseconds>(duration).count()<<"ms";
    }
};

b) एक सुविधाजनक मैक्रो जोड़ें जो TAG के रूप में वर्तमान फ़ंक्शन नाम का उपयोग करता है (यहाँ एक मैक्रो का उपयोग करना महत्वपूर्ण है, अन्यथा आप जो फ़ंक्शन मापना चाहते हैं उसके बजाय __FUNCTION__मूल्यांकन करेंगेMeasureExecutionTime

#ifndef MEASURE_FUNCTION_EXECUTION_TIME
#define MEASURE_FUNCTION_EXECUTION_TIME const MeasureExecutionTime measureExecutionTime(__FUNCTION__);
#endif

c) जिस फ़ंक्शन को आप मापना चाहते हैं, उसके आरंभ में अपना मैक्रो लिखें। उदाहरण:

 void DecodeMJPEGtoANativeWindowBuffer(uvc_frame_t* frame_mjpeg,const ANativeWindow_Buffer& nativeWindowBuffer){
        MEASURE_FUNCTION_EXECUTION_TIME
        // Do some time-critical stuff 
}

जिसके परिणामस्वरूप निम्नलिखित आउटपुट होंगे:

ExecutionTime: For DecodeMJPEGtoANativeWindowBuffer is 54ms

ध्यान दें कि यह (अन्य सभी सुझाए गए समाधानों के रूप में) आपके फ़ंक्शन को कॉल किए जाने के बीच के समय को मापेगा और जब यह लौटा, तो उस समय नहीं जब आपके CPU फ़ंक्शन को निष्पादित कर रहा था। हालाँकि, यदि आप शेड्यूलर को नींद () या इसी तरह कॉल करके अपने रनिंग कोड को निलंबित करने के लिए कोई बदलाव नहीं देते हैं, तो इसके बीच कोई अंतर नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.