आसानी से बीता हुआ समय नापते हैं


297

मैं अपने कार्यक्रम के विभिन्न बिंदुओं को मापने के लिए समय () का उपयोग करने की कोशिश कर रहा हूं।

मुझे समझ में नहीं आ रहा है कि पहले और बाद में मान समान क्यों हैं? मैं समझता हूं कि यह मेरे कार्यक्रम को प्रोफाइल करने का सबसे अच्छा तरीका नहीं है, मैं बस यह देखना चाहता हूं कि कुछ कितना समय लेता है।

printf("**MyProgram::before time= %ld\n", time(NULL));

doSomthing();
doSomthingLong();

printf("**MyProgram::after time= %ld\n", time(NULL));

मैंने कोशिश की है:

struct timeval diff, startTV, endTV;

gettimeofday(&startTV, NULL); 

doSomething();
doSomethingLong();

gettimeofday(&endTV, NULL); 

timersub(&endTV, &startTV, &diff);

printf("**time taken = %ld %ld\n", diff.tv_sec, diff.tv_usec);

मैं इसका परिणाम कैसे पढ़ूं **time taken = 0 26339? क्या इसका मतलब 26,339 नैनोसेकेंड = 26.3 मिसे है?

किस बारे में **time taken = 4 45025, 4 सेकंड और 25 मिसेक का मतलब है?


10
मुझे सवाल समझ नहीं आ रहा है। बेशक मूल्य अलग हैं। बीच में समय बीत गया, इसलिए time()एक अलग मूल्य देता है।
थॉमस

1
आपका क्या मतलब है "मुझे समझ नहीं आ रहा है कि पहले और बाद के मूल्य अलग क्यों हैं"? आप वर्तमान समय (1 जनवरी, 1970 से सेकंड में) प्राप्त कर रहे हैं time(NULL)... दूसरी बार जब आप इसे कॉल करते हैं, तो यह पहले के बाद एन सेकंड होगा और इस प्रकार ... अलग-अलग (जब तक कि आप जो भी कर रहे हैं वह doesn ' t पूरा होने में दूसरा समय लें ... किस स्थिति में, यह पहले जैसा होगा)।
ब्रायन रोच

1
क्या आप हमें बता सकते हैं कि यह क्या प्रिंट करता है, और अगर आपको स्टॉपवॉच या दीवार घड़ी (या कैलेंडर) के साथ समय लगता है तो कितना समय लगेगा?
मैट कर्टिस

4
क्षमा करें, मेरा मतलब है कि दोनों मूल्य समान हैं। मैं अपना प्रश्न गलत टाइप करता हूं।
hap497

2
इस सूत्र को देखें: stackoverflow.com/questions/275004/…
डिफ़ॉल्ट

जवाबों:


334
//***C++11 Style:***
#include <chrono>

std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();

std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << "[µs]" << std::endl;
std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::nanoseconds> (end - begin).count() << "[ns]" << std::endl;

10
हाँ, इसका उत्तर होना चाहिए
फेरेंक डेका

23
इस चलाने के लिए आप जोड़ने के लिए #include <chrono>निर्देश और मैं के रूप में रिपोर्टिंग समय बदल जाएगा: std::cout << "Time difference (sec) = " << (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) /1000000.0 <<std::endl;(और सी ++ 11 झंडा जब संकलन भूल नहीं है: -std=c++11)
Antonello

1
वैसे, यह सीपीयू समय को मापता है, न कि दीवार घड़ी का समय। सही?
निकोस

4
@ RestlessC0bra, cppreference पर डॉक्स के अनुसार, "यह घड़ी दीवार घड़ी के समय से संबंधित नहीं है (उदाहरण के लिए, यह अंतिम रिबूट के बाद का समय हो सकता है), और अंतराल को मापने के लिए सबसे उपयुक्त है।"
सिलसिला

1
यह किस प्रकार का डेटा है? Std :: chrono :: period_cast <std :: chrono :: microseconds> (अंत - आरंभ) (.count) ()
sqp_125

272
#include <ctime>

void f() {
  using namespace std;
  clock_t begin = clock();

  code_to_time();

  clock_t end = clock();
  double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
}

time()समारोह केवल एक दूसरे के भीतर करने के लिए सही है, लेकिन देखते हैं CLOCKS_PER_SEC"घड़ियों" एक दूसरी के भीतर। अति-सरलीकृत होने के बावजूद यह एक आसान, पोर्टेबल माप है।


129
ध्यान रखें कि clock()सीपीयू समय को मापता है, न कि वास्तविक समय को समाप्त (जो बहुत अधिक हो सकता है)।
jlstrecker

12
जब क्लस्टर के लिए समानांतर कोड प्रोग्रामिंग, इस विधि वास्तविक दुनिया समय को प्रतिबिंबित नहीं करता है ...
निकोलस हैमिल्टन

3
यह सबसे आसान तरीका है। क्या आप @jlstrecker की टिप्पणी को अद्यतन या संबोधित करना पसंद करेंगे?
लोराह अटकिंस

5
ऊपर पोस्ट किया गया समाधान कई कारणों से एक अच्छा समाधान नहीं है। यह सही उत्तर है - stackoverflow.com/questions/2962785/…
Xofo

1
मैंने इस समाधान की कोशिश की, और जैसा कि टिप्पणियों ने सुझाव दिया, मेरा टाइमर वास्तविक दुनिया के समय में बहुत तेजी से भाग गया।
आरटीबार्क

267

आप समय मापने वाले तंत्र को सार कर सकते हैं और प्रत्येक कॉल करने योग्य रन समय को न्यूनतम अतिरिक्त कोड से मापा जा सकता है, बस एक टाइमर संरचना के माध्यम से बुलाया जा सकता है। इसके अलावा, संकलन समय पर आप कर सकते हैं टाइमिंग प्रकार (मिलीसेकंड, नैनोसेकंड आदि) परिमार्जित

लोकी एस्टरी की समीक्षा और वैरेडिक टेम्प्लेट का उपयोग करने के सुझाव के लिए धन्यवाद। यही कारण है कि अग्रेषित फ़ंक्शन कॉल।

#include <iostream>
#include <chrono>

template<typename TimeT = std::chrono::milliseconds>
struct measure
{
    template<typename F, typename ...Args>
    static typename TimeT::rep execution(F&& func, Args&&... args)
    {
        auto start = std::chrono::steady_clock::now();
        std::forward<decltype(func)>(func)(std::forward<Args>(args)...);
        auto duration = std::chrono::duration_cast< TimeT> 
                            (std::chrono::steady_clock::now() - start);
        return duration.count();
    }
};

int main() {
    std::cout << measure<>::execution(functor(dummy)) << std::endl;
}

Demo

हॉवर्ड हेन्ट की टिप्पणी के अनुसार जब तक हमें ऐसा नहीं करना है तब तक क्रोनो सिस्टम से बचना सबसे अच्छा है। इसलिए उपरोक्त वर्ग उपयोगकर्ता को countअतिरिक्त स्थैतिक विधि प्रदान करके मैन्युअल रूप से कॉल करने का विकल्प दे सकता है (C ++ 14 में दिखाया गया है)

template<typename F, typename ...Args>
static auto duration(F&& func, Args&&... args)
{
    auto start = std::chrono::steady_clock::now();
    std::forward<decltype(func)>(func)(std::forward<Args>(args)...);
    return std::chrono::duration_cast<TimeT>(std::chrono::steady_clock::now()-start);
} 

// call .count() manually later when needed (eg IO)
auto avg = (measure<>::duration(func) + measure<>::duration(func)) / 2.0;

और ग्राहकों के लिए सबसे उपयोगी हो

"I / O (उदाहरण के लिए औसत) से पहले अवधि का एक गुच्छा संसाधित करना चाहते हैं"


पूरा कोड यहां पाया जा सकता है । क्रोनो पर आधारित बेंचमार्किंग टूल बनाने का मेरा प्रयास यहाँ दर्ज है


यदि C ++ 17 std::invokeउपलब्ध है, तो कॉल करने योग्य का आह्वानexecution इस तरह किया जा सकता है:

invoke(forward<decltype(func)>(func), forward<Args>(args)...);

कॉलबल्स के लिए प्रदान करने के लिए जो सदस्य कार्यों के लिए संकेत हैं।


2
अच्छा; मेरे पास मेरे कोड में कुछ समान है, लेकिन कक्षा में एक अलग इंटरफ़ेस का उपयोग करें: मेरे पास एक वर्ग ( code_timer) है जो std::chrono::system_clock::now();निर्माणकर्ता में प्रारंभ समय ( ) लेता है , एक विधि code_timer::ellapsedजो एक नई now()कॉल और निर्माणकर्ता के बीच अंतर को मापती है , और एक code_timer::resetविधि जो नए now()परिणाम के लिए प्रारंभ समय को रीसेट करती है । मेरे कोड में एक फ़नकार के निष्पादन को मापने के लिए, मैं कक्षा के बाहर एक निशुल्क फ़ंक्शन का उपयोग करता हूं। यह किसी ऑब्जेक्ट के निर्माण से लेकर एसिंनच कॉल के समापन तक समय को मापने की अनुमति देता है।
उत्तानपश्चिम '

7
<नाइटपिक>: chronoसिस्टम से बाहर न निकलें जब तक आपको (उपयोग से बचना .count()) नहीं है। .count()जब ग्राहक को मजबूर किया जाए (I / O के लिए कहें, जो वास्तव में दुर्भाग्यपूर्ण है)। ग्राहक I / O (जैसे औसत) से पहले अवधि का एक गुच्छा पोस्ट-प्रोसेस करना चाह सकता है और यह chronoसिस्टम के भीतर सबसे अच्छा किया जाता है।
हावर्ड हिनांत

1
@ user3241228 1. VS2013 ऑटो रिटर्न प्रकारों का समर्थन नहीं करता है (सिर्फ रिटर्न रिटर्न प्रकार - यह एक c ++ 14 फीचर अभी तक नहीं है)। 2. मेरा मानना ​​है कि यह कारण है लेकिन मैंने अक को सिर्फ निश्चित होने के लिए कहा है
निकोस अथानासीओ

2
क्यों नहीं std::forward<F>(func)?
ओलियोरा

3
@oliora यह एक ही बात है। मैं पसंद करता हूं std::forward<decltype(func)>(func)क्योंकि यह जेनेरिक लैम्ब्डा ( auto&& func) के तर्क पर लागू हो सकता है जहां Fवाक्य-रचना नहीं है और यह एक उपयोगिता मैक्रो में अमूर्त करना आसान है #define fw(arg) std::forward<decltype(arg)>(arg)जो मैं अपने बेंचमार्क लाइब्रेरी में करता हूं (इसलिए यह एक सिंटैक्टिक बचा है, जिस पर मैं बहुत अधिक नहीं हूं। उत्तर)
निकोस अथानासीउ

56

जैसा कि मैं आपके प्रश्न से देख सकता हूं, ऐसा लगता है कि आप किसी कोड के निष्पादन के बाद बीता हुआ समय जानना चाहते हैं। मुझे लगता है कि आप दूसरे (ओं) में परिणाम देखने के लिए सहज होंगे। यदि ऐसा है, तो difftime()नीचे दिखाए अनुसार फ़ंक्शन का उपयोग करने का प्रयास करें। आशा है इससे तुम्हारी समस्या का समाधान हो गया होगा।

#include <time.h>
#include <stdio.h>

time_t start,end;
time (&start);
.
.
.
<your code>
.
.
.
time (&end);
double dif = difftime (end,start);
printf ("Elasped time is %.2lf seconds.", dif );

4
यह हमेशा मुझे पूर्णांक सेकंड देता है। क्या ऐसा होनेवाला है?
सोडियमनेट्रेट्रेट

10
समय हमेशा केवल कुछ सेकंड का होगा, इसलिए इसका उपयोग उप-दूसरे मापों के लिए नहीं किया जा सकता है।
दीप डेडपूल

31

केवल Windows: (लिनक्स टैग को इस उत्तर को पोस्ट करने के बाद जोड़ा गया था)

सिस्टम शुरू होने के बाद से मिलीसेकंड की संख्या प्राप्त करने के लिए आप GetTickCount () का उपयोग कर सकते हैं ।

long int before = GetTickCount();

// Perform time-consuming operation

long int after = GetTickCount();

7
मैं इसे लिनक्स पर उपयोग कर रहा हूं। इसलिए मैं GetTickCount () फ़ंक्शन का उपयोग नहीं कर सकता।
hap497

1
पहले से ही कोई बात नहीं;) अपनी पोस्ट के टैग को अपडेट करने के लिए धन्यवाद
RvdK

यह काम करता है और वास्तविक समय देता है, सीपीयू समय नहीं। मैंने इसे SleepEx(5000,0)// समय-सेवन के संचालन और के अंतर के स्थान पर रखकर परीक्षण किया afterऔर beforeलगभग 5 सेकंड था।
रुचिर

14

time(NULL)01/01/1970 से 00:00 ( युग ) के बाद से समाप्त सेकंड की संख्या । तो दो मानों के बीच का अंतर आपके द्वारा किए गए सेकंड की संख्या है।

int t0 = time(NULL);
doSomthing();
doSomthingLong();
int t1 = time(NULL);

printf ("time = %d secs\n", t1 - t0);

आप इसके साथ बेहतर परिणाम प्राप्त कर सकते हैं getttimeofday(), जो वर्तमान समय को सेकंड में वापस time()करता है , जैसा कि माइक्रोसेकंड में भी होता है।


13

समय (NULL) फ़ंक्शन 01/01/1970 से 00:00 बजे के बाद समाप्त हुए सेकंड की संख्या लौटाएगा। और क्योंकि, उस फ़ंक्शन को आपके प्रोग्राम में अलग-अलग समय पर कॉल किया जाता है, यह हमेशा C ++ में अलग-अलग समय होगा


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

12
struct profiler
{
    std::string name;
    std::chrono::high_resolution_clock::time_point p;
    profiler(std::string const &n) :
        name(n), p(std::chrono::high_resolution_clock::now()) { }
    ~profiler()
    {
        using dura = std::chrono::duration<double>;
        auto d = std::chrono::high_resolution_clock::now() - p;
        std::cout << name << ": "
            << std::chrono::duration_cast<dura>(d).count()
            << std::endl;
    }
};

#define PROFILE_BLOCK(pbn) profiler _pfinstance(pbn)

उपयोग नीचे है ::

{
    PROFILE_BLOCK("Some time");
    // your code or function
}

यह गुंजाइश में RAII के समान है

ध्यान दें कि यह मेरा नहीं है, लेकिन मुझे लगा कि यह यहाँ प्रासंगिक था


1
शामिल लापता
Stepan याकोवेंको

9
#include<time.h> // for clock
#include<math.h> // for fmod
#include<cstdlib> //for system
#include <stdio.h> //for delay

using namespace std;

int main()
{


   clock_t t1,t2;

   t1=clock(); // first time capture

   // Now your time spanning loop or code goes here
   // i am first trying to display time elapsed every time loop runs

   int ddays=0; // d prefix is just to say that this variable will be used for display
   int dhh=0;
   int dmm=0;
   int dss=0;

   int loopcount = 1000 ; // just for demo your loop will be different of course

   for(float count=1;count<loopcount;count++)
   {

     t2=clock(); // we get the time now

     float difference= (((float)t2)-((float)t1)); // gives the time elapsed since t1 in milliseconds

    // now get the time elapsed in seconds

    float seconds = difference/1000; // float value of seconds
    if (seconds<(60*60*24)) // a day is not over
    {
        dss = fmod(seconds,60); // the remainder is seconds to be displayed
        float minutes= seconds/60;  // the total minutes in float
        dmm= fmod(minutes,60);  // the remainder are minutes to be displayed
        float hours= minutes/60; // the total hours in float
        dhh= hours;  // the hours to be displayed
        ddays=0;
    }
    else // we have reached the counting of days
    {
        float days = seconds/(24*60*60);
        ddays = (int)(days);
        float minutes= seconds/60;  // the total minutes in float
        dmm= fmod(minutes,60);  // the rmainder are minutes to be displayed
        float hours= minutes/60; // the total hours in float
        dhh= fmod (hours,24);  // the hours to be displayed

    }

    cout<<"Count Is : "<<count<<"Time Elapsed : "<<ddays<<" Days "<<dhh<<" hrs "<<dmm<<" mins "<<dss<<" secs";


    // the actual working code here,I have just put a delay function
    delay(1000);
    system("cls");

 } // end for loop

}// end of main 

3
जब भी आपके उत्तर की सराहना की जाती है, हम कोड के एक संक्षिप्त विवरण के साथ एक पूर्व-amble पसंद करते हैं। धन्यवाद।
केव

2
यह बीता हुआ समय नहीं है, बल्कि प्रोसेसर का समय है।
जॉनीजेड

8

आपके दूसरे प्रोग्राम द्वारा मुद्रित मूल्य सेकंड और माइक्रोसेकंड हैं।

0 26339 = 0.026'339 s =   26339 µs
4 45025 = 4.045'025 s = 4045025 µs

8
#include <ctime>
#include <cstdio>
#include <iostream>
#include <chrono>
#include <sys/time.h>
using namespace std;
using namespace std::chrono;

void f1()
{
  high_resolution_clock::time_point t1 = high_resolution_clock::now();
  high_resolution_clock::time_point t2 = high_resolution_clock::now();
  double dif = duration_cast<nanoseconds>( t2 - t1 ).count();
  printf ("Elasped time is %lf nanoseconds.\n", dif );
}

void f2()
{
  timespec ts1,ts2;
  clock_gettime(CLOCK_REALTIME, &ts1);
  clock_gettime(CLOCK_REALTIME, &ts2);
  double dif = double( ts2.tv_nsec - ts1.tv_nsec );
  printf ("Elasped time is %lf nanoseconds.\n", dif );
}

void f3()
{
  struct timeval t1,t0;
  gettimeofday(&t0, 0);
  gettimeofday(&t1, 0);
  double dif = double( (t1.tv_usec-t0.tv_usec)*1000);
  printf ("Elasped time is %lf nanoseconds.\n", dif );
}
void f4()
{
  high_resolution_clock::time_point t1 , t2;
  double diff = 0;
  t1 = high_resolution_clock::now() ;
  for(int i = 1; i <= 10 ; i++)
  {
    t2 = high_resolution_clock::now() ;
    diff+= duration_cast<nanoseconds>( t2 - t1 ).count();
    t1 = t2;
  }
  printf ("high_resolution_clock:: Elasped time is %lf nanoseconds.\n", diff/10 );
}

void f5()
{
  timespec ts1,ts2;
  double diff = 0;
  clock_gettime(CLOCK_REALTIME, &ts1);
  for(int i = 1; i <= 10 ; i++)
  {
    clock_gettime(CLOCK_REALTIME, &ts2);
    diff+= double( ts2.tv_nsec - ts1.tv_nsec );
    ts1 = ts2;
  }
  printf ("clock_gettime:: Elasped time is %lf nanoseconds.\n", diff/10 );
}

void f6()
{
  struct timeval t1,t2;
  double diff = 0;
  gettimeofday(&t1, 0);
  for(int i = 1; i <= 10 ; i++)
  {
    gettimeofday(&t2, 0);
    diff+= double( (t2.tv_usec-t1.tv_usec)*1000);
    t1 = t2;
  }
  printf ("gettimeofday:: Elasped time is %lf nanoseconds.\n", diff/10 );
}

int main()
{
  //  f1();
  //  f2();
  //  f3();
  f6();
  f4();
  f5();
  return 0;
}

4

C ++ std :: क्रोनो को क्रॉस-प्लेटफॉर्म होने का स्पष्ट लाभ है। हालाँकि, यह POSIX clock_gettime () की तुलना में एक महत्वपूर्ण ओवरहेड भी पेश करता है। मेरे लिनक्स बॉक्स पर सभी std::chrono::xxx_clock::now()जायके लगभग एक ही प्रदर्शन करते हैं:

std::chrono::system_clock::now()
std::chrono::steady_clock::now()
std::chrono::high_resolution_clock::now()

हालांकि POSIX clock_gettime(CLOCK_MONOTONIC, &time)समान होना चाहिए, steady_clock::now()लेकिन यह x3 से अधिक गुना तेज है!

यहाँ मेरी परीक्षा है, पूर्णता के लिए।

#include <stdio.h>
#include <chrono>
#include <ctime>

void print_timediff(const char* prefix, const struct timespec& start, const 
struct timespec& end)
{
    double milliseconds = end.tv_nsec >= start.tv_nsec
                        ? (end.tv_nsec - start.tv_nsec) / 1e6 + (end.tv_sec - start.tv_sec) * 1e3
                        : (start.tv_nsec - end.tv_nsec) / 1e6 + (end.tv_sec - start.tv_sec - 1) * 1e3;
    printf("%s: %lf milliseconds\n", prefix, milliseconds);
}

int main()
{
    int i, n = 1000000;
    struct timespec start, end;

    // Test stopwatch
    clock_gettime(CLOCK_MONOTONIC, &start);
    for (i = 0; i < n; ++i) {
        struct timespec dummy;
        clock_gettime(CLOCK_MONOTONIC, &dummy);
    }
    clock_gettime(CLOCK_MONOTONIC, &end);
    print_timediff("clock_gettime", start, end);

    // Test chrono system_clock
    clock_gettime(CLOCK_MONOTONIC, &start);
    for (i = 0; i < n; ++i)
        auto dummy = std::chrono::system_clock::now();
    clock_gettime(CLOCK_MONOTONIC, &end);
    print_timediff("chrono::system_clock::now", start, end);

    // Test chrono steady_clock
    clock_gettime(CLOCK_MONOTONIC, &start);
    for (i = 0; i < n; ++i)
        auto dummy = std::chrono::steady_clock::now();
    clock_gettime(CLOCK_MONOTONIC, &end);
    print_timediff("chrono::steady_clock::now", start, end);

    // Test chrono high_resolution_clock
    clock_gettime(CLOCK_MONOTONIC, &start);
    for (i = 0; i < n; ++i)
        auto dummy = std::chrono::high_resolution_clock::now();
    clock_gettime(CLOCK_MONOTONIC, &end);
    print_timediff("chrono::high_resolution_clock::now", start, end);

    return 0;
}

और यह मुझे gcc7.2 -O3 के साथ संकलित होने पर मिलने वाला आउटपुट है:

clock_gettime: 24.484926 milliseconds
chrono::system_clock::now: 85.142108 milliseconds
chrono::steady_clock::now: 87.295347 milliseconds
chrono::high_resolution_clock::now: 84.437838 milliseconds

3

time(NULL)समारोह कॉल सेकंड की संख्या वापस आ जाएगी EPOC के बाद बीते: 1 जनवरी 1970 आप दो timestamps के बीच का अंतर ले जाता है, तो इसका मतलब यह शायद क्या:

size_t start = time(NULL);
doSomthing();
doSomthingLong();

printf ("**MyProgram::time elapsed= %lds\n", time(NULL) - start);

3

जैसा कि दूसरों ने पहले ही नोट किया है, सी मानक पुस्तकालय में समय () फ़ंक्शन का एक सेकंड से बेहतर रिज़ॉल्यूशन नहीं है। एकमात्र पूर्ण पोर्टेबल सी फ़ंक्शन जो बेहतर रिज़ॉल्यूशन प्रदान कर सकता है, वह घड़ी () प्रतीत होता है, लेकिन यह प्रोसेसर के समय को वॉलकॉक के समय के बजाय मापता है। यदि कोई अपने को POSIX प्लेटफार्मों (जैसे लिनक्स) पर सीमित करने के लिए सामग्री है, तो घड़ी_गेटटाइम () फ़ंक्शन एक अच्छा विकल्प है।

C ++ 11 के बाद से, बेहतर समय सुविधाएं हैं उपलब्ध हैं जो एक ऐसे फॉर्म में बेहतर रिज़ॉल्यूशन प्रदान करती हैं जो विभिन्न कंपाइलरों और ऑपरेटिंग सिस्टमों में बहुत पोर्टेबल होना चाहिए। इसी तरह, बढ़ावा :: डेटाइम लाइब्रेरी अच्छी उच्च-रिज़ॉल्यूशन टाइमिंग कक्षाएं प्रदान करती है जो अत्यधिक पोर्टेबल होनी चाहिए।

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

के साथ मदद करने के लिए इन सभी पोर्टेबिलिटी और आँकड़े-सभा के मुद्दों, मैं CXX-rtimers पर पुस्तकालय उपलब्ध विकासशील किया गया है Github जो सी ++ कोड के समय ब्लॉक के लिए एक सरल एपीआई प्रदान करने के लिए, शून्य त्रुटियों कंप्यूटिंग की कोशिश करता है, और रिपोर्टिंग एकाधिक टाइमर से आँकड़े एम्बेडेड आपके कोड में यदि आपके पास C ++ 11 संकलक है, तो आप बस #include <rtimers/cxx11.hpp>, और कुछ का उपयोग करें:

void expensiveFunction() {
    static rtimers::cxx11::DefaultTimer timer("expensiveFunc");
    auto scopedStartStop = timer.scopedStart();
    // Do something costly...
}

प्रोग्राम से बाहर निकलने पर, आपको std :: cerr जैसे लिखे गए समय आँकड़े का सारांश मिलेगा:

Timer(expensiveFunc): <t> = 6.65289us, std = 3.91685us, 3.842us <= t <= 63.257us (n=731)

जो औसत समय, इसके मानक-विचलन, ऊपरी और निचली सीमाओं को दिखाता है, और इस फ़ंक्शन को कितनी बार कहा गया।

यदि आप लिनक्स-विशिष्ट टाइमिंग फ़ंक्शन का उपयोग करना चाहते हैं, तो आप कर सकते हैं #include <rtimers/posix.hpp>, या यदि आपके पास बूस्ट लाइब्रेरी हैं, लेकिन पुराने सी ++ कंपाइलर हैं, तो आप कर सकते हैं #include <rtimers/boost.hpp>। इन टाइमर कक्षाओं के संस्करण भी हैं जो कई थ्रेड्स से सांख्यिकीय समय की जानकारी एकत्र कर सकते हैं। ऐसे तरीके भी हैं जो आपको सिस्टम घड़ी के तुरंत दो निरंतर प्रश्नों से जुड़े शून्य-त्रुटि का अनुमान लगाने की अनुमति देते हैं।


2

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


2

क्या देख रहा है से, tv_sec अलग-अलग सेकंड संग्रहीत करता है जबकि tv_usec ने microseconds को अलग से संग्रहीत किया है। और वे एक दूसरे के रूपांतरण नहीं हैं। इसलिए, उन्हें उचित इकाई में बदल दिया जाना चाहिए और कुल समय बीतने के लिए जोड़ा जाना चाहिए।

struct timeval startTV, endTV;

gettimeofday(&startTV, NULL); 

doSomething();
doSomethingLong();

gettimeofday(&endTV, NULL); 

printf("**time taken in microseconds = %ld\n",
    (endTV.tv_sec * 1e6 + endTV.tv_usec - (startTV.tv_sec * 1e6 + startTV.tv_usec))
    );

2

Linux पर, clock_gettime () अच्छे विकल्पों में से एक है। आपको वास्तविक समय लाइब्रेरी (-lrt) लिंक करना होगा।

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

#define BILLION  1000000000L;

int main( int argc, char **argv )
  {
    struct timespec start, stop;
    double accum;

    if( clock_gettime( CLOCK_REALTIME, &start) == -1 ) {
      perror( "clock gettime" );
      exit( EXIT_FAILURE );
    }

    system( argv[1] );

    if( clock_gettime( CLOCK_REALTIME, &stop) == -1 ) {
      perror( "clock gettime" );
      exit( EXIT_FAILURE );
    }

    accum = ( stop.tv_sec - start.tv_sec )
          + ( stop.tv_nsec - start.tv_nsec )
            / BILLION;
    printf( "%lf\n", accum );
    return( EXIT_SUCCESS );
  }

2

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

इस तरह से मैं कोड (ब्लॉक या वास्तव में किसी भी गुंजाइश) की शुरुआत में कोड ब्लॉक की शुरुआत में इन वस्तुओं में से किसी एक को तात्कालिक रूप से लेते हुए दीवार-समय को माप सकता हूं और तब उदाहरणों को नष्ट करने की अनुमति देता हूं क्योंकि बीता हुआ समय उदाहरण के दायरे से बाहर जाने पर निर्माण। आप यहां पूरा उदाहरण पा सकते हैं लेकिन संरचना अत्यंत सरल है:

template <typename clock_t = std::chrono::steady_clock>
struct scoped_timer {
  using duration_t = typename clock_t::duration;
  const std::function<void(const duration_t&)> callback;
  const std::chrono::time_point<clock_t> start;

  scoped_timer(const std::function<void(const duration_t&)>& finished_callback) :
      callback(finished_callback), start(clock_t::now()) { }
  scoped_timer(std::function<void(const duration_t&)>&& finished_callback) :
      callback(finished_callback), start(clock_t::now()) { }
  ~scoped_timer() { callback(clock_t::now() - start); }
};

संरचना आपको प्रदान की गई फ़न्क्टर पर वापस बुलाएगी जब वह दायरे से बाहर हो जाएगी ताकि आप समय की जानकारी के साथ कुछ कर सकें (इसे प्रिंट करें या इसे स्टोर करें या जो भी हो)। आप कुछ करने के लिए की जरूरत है और भी जटिल तुम भी इस्तेमाल कर सकते हैं std::bindके साथ std::placeholdersअधिक तर्क के साथ कार्यों को कालबैक में।

यहां इसका उपयोग करने का एक त्वरित उदाहरण दिया गया है:

void test(bool should_throw) {
  scoped_timer<> t([](const scoped_timer<>::duration_t& elapsed) {
    auto e = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(elapsed).count();
    std::cout << "took " << e << "ms" << std::endl;
  });

  std::this_thread::sleep_for(std::chrono::seconds(1));

  if (should_throw)
    throw nullptr;

  std::this_thread::sleep_for(std::chrono::seconds(1));
}

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


1

वे समान हैं क्योंकि आपका डोज़िमेटिंग फ़ंक्शन टाइमर की ग्रैन्युलैरिटी की तुलना में तेज़ी से होता है। प्रयत्न:

printf ("**MyProgram::before time= %ld\n", time(NULL));

for(i = 0; i < 1000; ++i) {
    doSomthing();
    doSomthingLong();
}

printf ("**MyProgram::after time= %ld\n", time(NULL));

1

कारण दोनों मान समान हैं क्योंकि आपकी लंबी प्रक्रिया है इतना लंबा समय नहीं लगता - एक सेकंड से भी कम। आप केवल एक लंबा लूप जोड़ने की कोशिश कर सकते हैं (उदाहरण के लिए (i = 0; मैं <100000000; i ++);) फ़ंक्शन के अंत में यह सुनिश्चित करने के लिए कि यह मुद्दा है, फिर हम वहां से जा सकते हैं ...

यदि उपरोक्त सही है, तो आपको एक और सिस्टम फ़ंक्शन खोजने की आवश्यकता होगी (मैं समझता हूं कि आप लिनक्स पर काम करते हैं, इसलिए समय को अधिक सटीक रूप से मापने के लिए मैं फ़ंक्शन नाम के साथ आपकी सहायता नहीं कर सकता)। मुझे यकीन है कि linux में GetTickCount () के लिए एक फंक्शन simular है, आपको बस इसे ढूंढने की आवश्यकता है।


1

मैं आमतौर पर निम्नलिखित का उपयोग करता हूं:

#include <chrono>
#include <type_traits>

using perf_clock = std::conditional<
    std::chrono::high_resolution_clock::is_steady,
    std::chrono::high_resolution_clock,
    std::chrono::steady_clock
>::type;

using floating_seconds = std::chrono::duration<double>;

template<class F, class... Args>
floating_seconds run_test(Func&& func, Args&&... args)
{
   const auto t0 = perf_clock::now();
   std::forward<Func>(func)(std::forward<Args>(args)...);
   return floating_seconds(perf_clock::now() - t0);
} 

यह @ nikos-athanasiou के समान है, सिवाय इसके कि मैं एक गैर-स्थिर घड़ी का उपयोग करने से बचता हूं और एक अवधि के रूप में सेकंड की फ्लोटिंग संख्या का उपयोग करता हूं।


1
इस प्रकार पर : आमतौर पर या high_resolution_clockतो के लिए एक typedef है । तो यह पता लगाने के लिए कि यदि भाग सत्य है, तो आप कौन सा (एक टाइपफाइफ़) है । अगर यह गलत है तो आप फिर से चुनें। बस शुरुआत से उपयोग करें ...system_clocksteady_clockstd::conditionalis_steadyhigh_resolution_clocksteady_clocksteady_clocksteady_clock
निकोस अथानासीओ

@ nikos-athanasiou मैं पूरी तरह से 5gon12eder की टिप्पणी से सहमत हूं कि मानक द्वारा "विशिष्ट" मामले की आवश्यकता नहीं है, इसलिए कुछ एसटीएल को अलग तरीके से लागू किया जा सकता है। मैं अपने कोड को अधिक सामान्य होना चाहता हूं और कार्यान्वयन विवरण पर संबंधित नहीं हूं।
ओलियोरा

यह आवश्यक नहीं है, लेकिन स्पष्ट रूप में कहा गया है 20.12.7.3 : high_resolution_clock may be a synonym for system_clock or steady_clock। इसका कारण यह है: high_resolution_clockसबसे छोटी टिक अवधि के साथ घड़ियों का प्रतिनिधित्व करता है, इसलिए जो भी कार्यान्वयन होता है, उसके दो विकल्प होते हैं, स्थिर होना या न होना। हम जो भी चुनाव करते हैं, यह कहते हुए कि कार्यान्वयन अन्य दो घड़ियों से भिन्न होगा, यह कहने जैसा है कि हमारे पास स्थिर (या नहीं) घड़ी के लिए बेहतर कार्यान्वयन है जिसे हम उपयोग करने के लिए नहीं चुनते हैं (स्थिर या घड़ियों के लिए नहीं)। यह जानना कि अच्छा कैसे है, यह जानना कि क्यों बेहतर है
निकोस अथानासीउ

@ निकोस-अथानासीउ मैं 100% सुरक्षित होना पसंद करूंगा, खासकर जब यह लागत मुझे कोई रनवे ओवरहेड और undetectable संकलित समय ओवरहेड। आप "हो सकता है" पर भरोसा कर सकते हैं और यदि आप चाहें, तो आश्वासन भी दे सकते हैं।
ओलियोरा

au मेरे दोस्त को नियंत्रित करता है, यह आप है जो "हो सकता है" पर निर्भर करता है, लेकिन अपने आप पर सूट करता है। यदि आप 100% सुनिश्चित होना चाहते हैं और यह लिखना जारी रखते हैं, तो आपको अलग-अलग घड़ियों के समय बिंदुओं को गैर-पोर्ट्रेट रूप से मिलाने से बचने के लिए, आपके और आपके कोड के उपयोगकर्ताओं के लिए भी एक रास्ता खोजना चाहिए (यदि कभी इस प्रकार स्विच का अर्थ प्राप्त होता है, तो) यह अलग-अलग प्लेटफार्मों पर अलग तरह से व्यवहार करेगा)। मज़े करो!
निकोस अथानासीउ

0

ओपी के तीन विशिष्ट सवालों के जवाब में।

"मुझे समझ में नहीं आ रहा है कि पहले और बाद में मूल्य समान क्यों हैं? "

पहला सवाल और नमूना कोड से पता चलता है कि time()इतना जवाब है, 1 सेकंड की एक संकल्प है होना करने के लिए है कि दो कार्यों 1 सेकंड से कम में निष्पादित। लेकिन कभी-कभी यह (जाहिरा तौर पर अतार्किक रूप से) 1 सेकंड की सूचना देगा यदि दो टाइमर निशान एक दूसरे की सीमा पर चलते हैं।

अगला उदाहरण उपयोग करता है gettimeofday()जो इस संरचना को भरता है

struct timeval {
    time_t      tv_sec;     /* seconds */
    suseconds_t tv_usec;    /* microseconds */
};

और दूसरा प्रश्न पूछता है: "मैं कैसे परिणाम करता हूं **time taken = 0 26339? क्या इसका मतलब 26,339 नैनोसेकंड = 26.3 इंच है?"

मेरा दूसरा उत्तर है, लिया गया समय 0 सेकंड और 26339 माइक्रोसेकंड है, जो 0.026339 सेकंड है, जो 1 सेकंड से कम समय में निष्पादित करने वाले पहले उदाहरण को बताता है।

तीसरा सवाल पूछते हैं: "क्या बारे में **time taken = 4 45025, कि मतलब 4 सेकंड और 25 msec है?"

मेरा तीसरा जवाब है, लिया गया समय 4 सेकंड और 45025 माइक्रोसेकंड है, जो कि 4.045025 सेकंड है, जो दर्शाता है कि ओपी ने दो कार्यों द्वारा किए गए कार्यों को बदल दिया है जो उसने पहले समयबद्ध किया था।


0
#include <ctime>
#include <functional>

using namespace std;

void f() {
  clock_t begin = clock();

  // ...code to measure time...

  clock_t end = clock();

  function<double(double, double)> convtime = [](clock_t begin, clock_t end)
  {
     return double(end - begin) / CLOCKS_PER_SEC;
  };

  printf("Elapsed time: %.2g sec\n", convtime(begin, end));

}

यहां उपलब्ध समान उदाहरण, केवल अतिरिक्त रूपांतरण फ़ंक्शन के साथ + प्रिंट आउट।


0

मैंने स्वचालित रूप से बीता हुआ समय मापने के लिए एक वर्ग बनाया है, कृपया इस लिंक में कोड (c ++ 11) देखें: देखें https://github.com/sonnt174/Common/blob/master/time_measure.h

क्लास टाइममेयर का उपयोग कैसे करें, इसका उदाहरण:

void test_time_measure(std::vector<int> arr) {
  TimeMeasure<chrono::microseconds> time_mea;  // create time measure obj
  std::sort(begin(arr), end(arr));
}

मुझे इकाइयों के साथ आपका प्रिंट स्टेटमेंट पसंद है। अपने कोड को gcc और क्लैग में पोर्ट करने में क्या लगेगा? ( wandbox.org )
हावर्ड हिनांत

1
@HowardHinnant: संबोधित करने के लिए धन्यवाद, मैंने gcc और क्लैंग के लिए भी कोड अपडेट किया।
सिरन गुयेन ट्रूंग

0

Matlab स्वाद!

ticप्रदर्शन को मापने के लिए एक स्टॉपवॉच टाइमर शुरू करता है। फ़ंक्शन टिक आदेश के निष्पादन में आंतरिक समय रिकॉर्ड करता है। tocफ़ंक्शन के साथ बीता हुआ समय प्रदर्शित करें ।

#include <iostream>
#include <ctime>
#include <thread>
using namespace std;

clock_t START_TIMER;

clock_t tic()
{
    return START_TIMER = clock();
}

void toc(clock_t start = START_TIMER)
{
    cout
        << "Elapsed time: "
        << (clock() - start) / (double)CLOCKS_PER_SEC << "s"
        << endl;
}

int main()
{
    tic();
    this_thread::sleep_for(2s);
    toc();

    return 0;
}

-4

आप एसएफएमएल पुस्तकालय का उपयोग कर सकते हैं , जो सरल और तेज मल्टीमीडिया लाइब्रेरी है। इसमें कई उपयोगी और अच्छी तरह से परिभाषित कक्षाएं जैसे घड़ी, सॉकेट, साउंड, ग्राफिक्स आदि शामिल हैं। यह उपयोग करना बहुत आसान है और अत्यधिक अनुशंसित है।

यह इस प्रश्न के लिए एक उदाहरण है।

sf::Clock clock;
...
Time time1 = clock.getElapsedTime();
...
Time time2 = clock.restart();
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.