অতিবাহিত সময় সহজেই পরিমাপ করুন


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
আপনার অর্থ কী? "আমি বুঝতে পারি না কেন আগে এবং পরে মানগুলি আলাদা হয়"? আপনি বর্তমান সময়টি পেয়ে যাচ্ছেন (১ জানুয়ারি, ১৯ 1970০ সাল থেকে কয়েক সেকেন্ডে) আপনি ব্যবহার করছেন time(NULL)... দ্বিতীয়বার আপনি যখন ফোন করবেন তখন এটি প্রথম সেকেন্ডের পরে হবে এবং এইভাবে ... আলাদা (যদি আপনি যা করেন না কেন) সম্পূর্ণ হতে এক সেকেন্ড লাগবে না ... এই ক্ষেত্রে এটি প্রথমটির মতোই হবে)।
ব্রায়ান রোচ

1
এটি কী প্রিন্ট করে তা আপনি কী বলতে পারেন এবং স্টপওয়াচ বা প্রাচীরের ঘড়িটি (বা একটি ক্যালেন্ডার) দিয়ে সময় দেওয়ার জন্য এটি কতক্ষণ সময় নেয়?
ম্যাট কার্টিস

4
দুঃখিত, আমার অর্থ উভয় মান একই আমি আমার প্রশ্নটি ভুল টাইপ করি।
hp497

2
এই থ্রেডটি দেখুন: stackoverflow.com/questions/275004/…
ডিফল্ট

উত্তর:


332
//***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)
আন্তোনেলো

1
যাইহোক, এটি সিপিইউ সময় পরিমাপ করে, প্রাচীর ঘড়ির সময় নয়। রাইট?
নিকোস

4
@ রেস্টলেস সি 0bra সিপ্রেফারেন্সির ডক্স অনুসারে, "এই ঘড়িটি প্রাচীর ঘড়ির সময়ের সাথে সম্পর্কিত নয় (উদাহরণস্বরূপ, এটি শেষ পুনরায় বুট করার পরে সময় হতে পারে), এবং অন্তরগুলি পরিমাপের জন্য সবচেয়ে উপযুক্ত is"
সাইলাস

1
কি ডাটা টাইপ এই হল এসটিডি :: chrono :: duration_cast <এসটিডি :: chrono :: মাইক্রোসেকেন্ড> (শেষ - শুরু)? .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

হাওয়ার্ড হিন্যান্টের মন্তব্য অনুসারে ক্রোনো সিস্টেম থেকে বেরিয়ে না আসাই সেরা best সুতরাং উপরের শ্রেণিটি countঅতিরিক্ত স্ট্যাটিক পদ্ধতি সরবরাহ করে ব্যবহারকারীকে ম্যানুয়ালি কল করতে পছন্দ করতে পারে (সি ++ এ দেখানো হয়েছে)

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 (যেমন গড়) এর পূর্বে একগুচ্ছ সময়কাল পোস্ট-প্রসেস করতে চান"


সম্পূর্ণ কোডটি এখানে পাওয়া যাবে । ক্রোনোর ​​উপর ভিত্তি করে একটি বেঞ্চমার্কিং সরঞ্জাম তৈরির আমার প্রচেষ্টা এখানে লিপিবদ্ধ আছে


যদি সি ++ 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()ফলাফলের সাথে পুনরায় সেট করে । আমার কোডে কোনও ফান্টারের কার্যকরকরণ পরিমাপ করতে, আমি ক্লাসের বাইরে একটি ফাংশন ব্যবহার করি। এটি কোনও অবজেক্ট তৈরি থেকে অ্যাসিঞ্চ কল শেষ পর্যন্ত সময় পরিমাপের অনুমতি দেয়।
utnapistim

7
<nitpick>: chronoযতক্ষণ না আপনার দরকার (ততক্ষণ ব্যবহার এড়ানো .count()) না হওয়া অবধি সিস্টেমের বাইরে পালাবেন না । .count()বাধ্য হয়ে ক্লায়েন্টকে কল করতে দিন (I / O এর জন্য বলুন, যা দুর্ভাগ্যজনক)। ক্লায়েন্ট I / O (যেমন গড়) এর পূর্বে একগুচ্ছ সময়কাল পোস্ট-প্রসেস করতে চাইতে পারে এবং এটি chronoসিস্টেমের মধ্যে সেরা হয়ে যায় ।
হাওয়ার্ড হিন্যান্ট

1
@ ব্যবহারকারী3241228 1. ভিএস2013 অটো রিটার্নের ধরণগুলিকে সমর্থন করে না (কেবল পিছনে ফিরে আসা প্রকারগুলি - এটি একটি সি ++ 14 বৈশিষ্ট্য এখনও উপলভ্য নয়) 2. আমি বিশ্বাস করি এই কারণ নেই কিন্তু আমি AQ জিজ্ঞাসা ঠিক নিশ্চিত হতে
নিকোস Athanasiou

2
না কেন std::forward<F>(func)?
অলিওরা

3
@ এলিওরা এটি একই জিনিস। আমি পছন্দ করি 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

শুধুমাত্র উইন্ডোজ: (আমি এই উত্তর পোস্ট করার পরে লিনাক্স ট্যাগ যুক্ত করা হয়েছিল)

সিস্টেমটি শুরু হওয়ার পর থেকে কাটিয়ে যাওয়া মিলিসেকেন্ডগুলির সংখ্যা পেতে আপনি গেটটিকাউন্ট () ব্যবহার করতে পারেন ।

long int before = GetTickCount();

// Perform time-consuming operation

long int after = GetTickCount();

7
আমি এটি লিনাক্সে ব্যবহার করছি। সুতরাং আমি গেটটিকাউন্ট () ফাংশনটি ব্যবহার করতে পারি না।
hap497

1
ইতিমধ্যে কিছু মনে করবেন না;) আপনার পোস্টটির ট্যাগ আপডেট করার জন্য ধন্যবাদ
আরভিডিকে

এটি কাজ করে এবং আসল সময় দেয়, সিপিইউয়ের সময় নয়। আমি 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

সময় (এনএইউএল) ফাংশনটি 01/01/1970 সাল থেকে 00:00 এ সময় পার হওয়া সেকেন্ডের সংখ্যা ফিরে আসবে। এবং কারণ, আপনার প্রোগ্রামে সেই ফাংশনটি বিভিন্ন সময়ে ডাকা হয়, এটি সি ++ এ সর্বদা আলাদা সময় হবে


আমি জানি না কেন কেউ কেন নিম্নচাপ দিয়েছে, কিন্তু আপনার উত্তর সম্পূর্ণ সঠিক নয়। প্রারম্ভিকদের জন্য এটি তারিখের সময় ফেরায় না এবং এটি সর্বদা আলাদা হবে না।
ম্যাট জয়েনার

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
অন্তর্ভুক্ত রয়েছে
স্টেপান ইয়াকোভেনকো

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
আপনার উত্তর প্রশংসা করা হয়, আমরা কোড একটি সংক্ষিপ্ত বিবরণ সমন্বিত একটি প্রাক অ্যাম্বল পছন্দ। ধন্যবাদ।
কেভ

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

সি ++ স্টেড :: ক্রোনোর ​​ক্রস প্ল্যাটফর্ম হওয়ার সুস্পষ্ট সুবিধা রয়েছে। তবে এটি পসিক্স ক্লক_গেটটাইম () এর সাথে তুলনা করে একটি উল্লেখযোগ্য ওভারহেড প্রবর্তন করে। আমার লিনাক্স বাক্সে সমস্ত std::chrono::xxx_clock::now()স্বাদ মোটামুটি একই করে:

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

যদিও পসিক্সের মতো clock_gettime(CLOCK_MONOTONIC, &time)হওয়া উচিতsteady_clock::now() তবে এটি এক্স 3 গুণ বেশি দ্রুত!

এখানে আমার পরীক্ষা, সম্পূর্ণতার জন্য।

#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 আপনি দুই টাইমস্ট্যাম্প মধ্যে পার্থক্য নেওয়া করতে হবে মানে সম্ভবত কি:

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

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

3

অন্যরা ইতিমধ্যে উল্লেখ করেছেন যে, সি স্ট্যান্ডার্ড লাইব্রেরিতে সময় () ফাংশনের একটি রেজুলেশন এক সেকেন্ডের চেয়ে ভাল হয় না। একমাত্র পুরোপুরি পোর্টেবল সি ফাংশন যা আরও ভাল রেজোলিউশন সরবরাহ করতে পারে তা হ'ল ঘড়ির () বলে মনে হয়, তবে এটি প্রাচীরের ঘড়ির সময়ের চেয়ে প্রসেসরের সময় পরিমাপ করে। যদি কেউ নিজেকে পসিক্স প্ল্যাটফর্মগুলিতে (যেমন লিনাক্স) সীমাবদ্ধ রাখার বিষয়বস্তু হয় তবে ক্লক_জেটটাইম () ফাংশনটি একটি ভাল পছন্দ।

সি ++ ১১ যেহেতু, সময় নির্ধারণের আরও অনেক সুবিধা রয়েছে রয়েছে যা একটি ফর্মে আরও ভাল রেজোলিউশন সরবরাহ করে যা বিভিন্ন সংকলক এবং অপারেটিং সিস্টেমের জুড়ে খুব বহনযোগ্য হওয়া উচিত। একইভাবে, বুস্ট :: ডেটটাইম লাইব্রেরি ভাল উচ্চ-রেজোলিউশন সময় ক্লাস সরবরাহ করে যা অত্যন্ত পোর্টেবল হতে হবে।

এর মধ্যে যে কোনও সুবিধা ব্যবহারের ক্ষেত্রে একটি চ্যালেঞ্জ হ'ল সিস্টেম ক্লকটি জিজ্ঞাসা করে সময় দেরি করা। ক্লক_জেটটাইম (), বুস্ট :: ডেটটাইম এবং স্টাড :: ক্রোনোর ​​সাথে পরীক্ষা করা থেকে এই বিলম্বটি সহজেই মাইক্রোসেকেন্ডগুলির বিষয় হতে পারে। সুতরাং, আপনার কোডের যে কোনও অংশের সময়কাল পরিমাপ করার সময়, আপনাকে এই আকারের চারপাশে কোনও পরিমাপের ত্রুটি থাকতে দেওয়া উচিত বা কোনওভাবে শূন্য-ত্রুটির জন্য সংশোধন করার চেষ্টা করতে হবে। আদর্শভাবে, আপনি ভালভাবে আপনার ফাংশন দ্বারা নেওয়া সময়ের একাধিক পরিমাপ সংগ্রহ করতে এবং গড়, বা বহু রান জুড়ে নেওয়া সর্বনিম্ন / সর্বনিম্ন / সময় গণনা করতে চাইতে পারেন।

সাহায্য করার জন্য এই সব বহনযোগ্যতা ও পরিসংখ্যান-জমায়েত বিষয়, আমি cxx-rtimers উপর গ্রন্থাগার প্রাপ্তিসাধ্য উন্নয়নশীল করে থাকেন গিটহাব যা সি ++ কোড সময়সীমাকে ব্লক জন্য একটি সহজ এপিআই প্রদান, শূন্য ত্রুটি কম্পিউটিং চেষ্টা করে, এবং প্রতিবেদন একাধিক টাইমার থেকে পরিসংখ্যান এমবেডেড আপনার কোডে আপনার যদি সি ++ 11 সংকলক থাকে তবে আপনি কেবল #include <rtimers/cxx11.hpp>, এবং এমন কিছু ব্যবহার করেন:

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

প্রোগ্রামের প্রস্থান থেকে, আপনি স্টাড :: সেররে লিখিত টাইমিং পরিসংখ্যানের সংক্ষিপ্তসার পাবেন যেমন:

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

যা গড় সময় দেখায়, এর মান-বিচ্যুতি, উপরের এবং নিম্ন সীমা এবং এই ফাংশনটির জন্য কতবার ডাকা হয়েছিল shows

আপনি যদি লিনাক্স-নির্দিষ্ট টাইমিং ফাংশন ব্যবহার করতে চান #include <rtimers/posix.hpp>তবে আপনি বা বুস্ট লাইব্রেরিগুলি থাকলেও একটি পুরানো সি ++ সংকলক করতে পারেন #include <rtimers/boost.hpp>। এই টাইমার ক্লাসগুলির সংস্করণগুলিও রয়েছে যা একাধিক থ্রেড থেকে পরিসংখ্যান সংক্রান্ত সময়কালের তথ্য সংগ্রহ করতে পারে। এমন কয়েকটি পদ্ধতি রয়েছে যা আপনাকে সিস্টেম ঘড়ির সাথে সাথে দুটি ক্রমাগত প্রশ্নের সাথে জিরো-ত্রুটি সম্পর্কিত অনুমান করতে দেয়।


2

অভ্যন্তরীণভাবে ফাংশনটি সিস্টেমের ঘড়িতে অ্যাক্সেস করবে, এ কারণেই এটি প্রতিবার আপনি যখন কল করবেন তখন এটি বিভিন্ন মান দেয়। অ-কার্যকরী ভাষার সাথে সাধারণভাবে ফাংশনগুলিতে অনেকগুলি পার্শ্ব প্রতিক্রিয়া এবং লুকানো অবস্থা থাকতে পারে যা আপনি কেবলমাত্র ফাংশনের নাম এবং যুক্তি দেখেই দেখতে পাচ্ছেন না।


2

যা দেখা যায়, সেখান থেকে টিভি_সেক্রেস সেকেন্ডটি বিভক্ত হয়ে যায় যখন টিভি_ ইউজেক মাইক্রোসেকেন্ডগুলি আলাদাভাবে সঞ্চিত করে। এবং তারা একে অপরের রূপান্তর নয়। সুতরাং, এগুলি যথাযথ ইউনিটে পরিবর্তন করতে হবে এবং মোট সময় ব্যয় করার জন্য যুক্ত করতে হবে।

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

লিনাক্সে, ক্লক_জেটটাইম () ভাল পছন্দগুলির মধ্যে একটি। আপনাকে অবশ্যই রিয়েল টাইম লাইব্রেরি (-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স্পষ্টভাবে শুরু করা এবং আপনার জন্য এটা করতে scoping উপর নির্ভর না করেই টাইমার থামাতে।


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

উভয় মান একই কারণ হ'ল আপনার দীর্ঘ প্রক্রিয়া এত বেশি সময় নেয় না - এক সেকেন্ডেরও কম। এই সমস্যাটি নিশ্চিত হওয়ার জন্য ফাংশন শেষে আপনি কেবলমাত্র একটি দীর্ঘ লুপ যুক্ত করার চেষ্টা করতে পারেন (এর জন্য (int i = 0; i <100000000; i ++);) তবে আমরা সেখান থেকে যেতে পারি ...

উপরেরটি সত্য হিসাবে প্রমাণিত হলে, সময়কে আরও সঠিকভাবে পরিমাপ করার জন্য আপনাকে একটি ভিন্ন সিস্টেমের ফাংশন (আমি বুঝতে পারছি আপনি লিনাক্সের উপর কাজ করেন তাই আমি আপনাকে ফাংশনটির নামটি সাহায্য করতে পারি না) find আমি নিশ্চিত যে লিনাক্সে গেটটিকাউন্ট () এর কোনও ফাংশন সিমুলার রয়েছে, আপনার এটি সন্ধান করা দরকার।


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);
} 

এটি @ নিকোস-অ্যাথানসিয়ো প্রস্তাবিত সমান। কেবলমাত্র আমি অবিচলিত ঘড়ি ব্যবহার করা এড়াতে পারি এবং সময়কাল হিসাবে সেকেন্ডের ভাসমান সংখ্যার ব্যবহার করি।


1
এই টাইপউইচটিতে : সাধারণত high_resolution_clockহয় হয় system_clockবা হয় জন্য একটি টাইপডেফsteady_clock । সুতরাং ট্রেস যে std::conditionalযদি is_steadyঅংশ সত্য হয় তাহলে আপনি বাছাই high_resolution_clockযা (ক করার মধ্যে typedef) steady_clock। যদি এটি মিথ্যা হয় তবে আপনি steady_clockআবার বাছাই করুন । কেবল steady_clockশুরু থেকে ব্যবহার করুন ...
নিকোস অথানাসিউ

@ নিকোস-অ্যাথানাসিও আমি 5gon12eder এর মন্তব্যে সম্পূর্ণরূপে একমত যে "আদর্শ" কেস স্ট্যান্ডার্ড দ্বারা আবশ্যক নয় তাই কিছু এসটিএল অন্যভাবে প্রয়োগ করা যেতে পারে। আমি আমার কোডটিকে আরও জেনেরিক এবং প্রয়োগের বিশদ সম্পর্কিত নয় এমন হতে পছন্দ করি।
অলিওরা

এটি প্রয়োজনীয় নয় তবে স্পষ্টভাবে 20.12.7.3 এ বর্ণিত হয়েছে : high_resolution_clock may be a synonym for system_clock or steady_clock. কারণটি হ'ল: high_resolution_clockসংক্ষিপ্ত টিকের সময়কালের সাথে ঘড়িগুলি উপস্থাপন করে, তাই বাস্তবায়ন যাই হোক না কেন, তার দুটি পছন্দ আছে, অবিচল থাকা বা না থাকা। আমরা যে কোনও পছন্দই করি না কেন, প্রয়োগটি অন্য দুটি ঘড়ির চেয়ে পৃথক হবে বলার মতো আমরা স্থির (বা না) ঘড়িটির জন্য আমাদের আরও ভাল বাস্তবায়ন করেছি যা আমরা ব্যবহার না করার জন্য বেছে নিই (অবিচলিত বা না ঘড়ির জন্য)। কীভাবে ভাল তা জানা, কেন আরও ভাল তা জেনে
নিকোস আটানাসিউউ

@ নিকোস-অ্যাথানাসিও আমি 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 সেকেন্ড, যা প্রথম সেকেন্ডের চেয়ে কম সময়ে নির্বাহের প্রথম উদাহরণ বহন করে।

তৃতীয় প্রশ্ন জিজ্ঞেস করল: "কি সম্পর্কে **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

আমি অতিবাহিত সময়কে স্বয়ংক্রিয়ভাবে পরিমাপ করার জন্য একটি শ্রেণি তৈরি করেছি, দয়া করে এই লিঙ্কে কোডটি (সি ++ 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));
}

আমি ইউনিটগুলির সাথে আপনার মুদ্রণ বিবরণী পছন্দ করি। আপনার কোডটি জিসিসি এবং বিড়ম্বনায় পোর্ট করতে কী লাগবে? ( ভ্যান্ডবক্স.অর্গ )
হাওয়ার্ড

1
@ হাওয়ার্ডহিন্যান্ট: সম্বোধনের জন্য ধন্যবাদ, আমি জিসিসি এবং ঝনঝনির জন্য কোডও আপডেট করেছি।
সেরন এনগুইন ট্রুং

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();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.