Easily measure elapsed time

前端 未结 26 2139
栀梦
栀梦 2020-11-22 04:13

I am trying to use time() to measure various points of my program.

What I don\'t understand is why the values in the before and after are the same? I understand thi

相关标签:
26条回答
  • 2020-11-22 04:53
    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)
    

    Usage is below ::

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

    THis is similar to RAII in scope

    NOTE this is not mine, but i thought it was relevant here

    0 讨论(0)
  • 2020-11-22 04:53

    They are they same because your doSomething function happens faster than the granularity of the timer. Try:

    printf ("**MyProgram::before time= %ld\n", time(NULL));
    
    for(i = 0; i < 1000; ++i) {
        doSomthing();
        doSomthingLong();
    }
    
    printf ("**MyProgram::after time= %ld\n", time(NULL));
    
    0 讨论(0)
  • 2020-11-22 04:56
    #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 
    
    0 讨论(0)
  • 2020-11-22 04:57

    You can abstract the time measuring mechanism and have each callable's run time measured with minimal extra code, just by being called through a timer structure. Plus, at compile time you can parametrize the timing type (milliseconds, nanoseconds etc).

    Thanks to the review by Loki Astari and the suggestion to use variadic templates. This is why the forwarded function call.

    #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

    According to the comment by Howard Hinnant it's best not to escape out of the chrono system until we have to. So the above class could give the user the choice to call count manually by providing an extra static method (shown in 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;
    

    and be most useful for clients that

    "want to post-process a bunch of durations prior to I/O (e.g. average)"


    The complete code can be found here. My attempt to build a benchmarking tool based on chrono is recorded here.


    If C++17's std::invoke is available, the invocation of the callable in execution could be done like this :

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

    to provide for callables that are pointers to member functions.

    0 讨论(0)
  • 2020-11-22 04:58

    Windows only: (The Linux tag was added after I posted this answer)

    You can use GetTickCount() to get the number of milliseconds that have elapsed since the system was started.

    long int before = GetTickCount();
    
    // Perform time-consuming operation
    
    long int after = GetTickCount();
    
    0 讨论(0)
  • 2020-11-22 04:58

    In answer to OP's three specific questions.

    "What I don't understand is why the values in the before and after are the same?"

    The first question and sample code shows that time() has a resolution of 1 second, so the answer has to be that the two functions execute in less than 1 second. But occasionally it will (apparently illogically) inform 1 second if the two timer marks straddle a one second boundary.

    The next example uses gettimeofday() which fills this struct

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

    and the second question asks: "How do I read a result of **time taken = 0 26339? Does that mean 26,339 nanoseconds = 26.3 msec?"

    My second answer is the time taken is 0 seconds and 26339 microseconds, that is 0.026339 seconds, which bears out the first example executing in less than 1 second.

    The third question asks: "What about **time taken = 4 45025, does that mean 4 seconds and 25 msec?"

    My third answer is the time taken is 4 seconds and 45025 microseconds, that is 4.045025 seconds, which shows that OP has altered the tasks performed by the two functions which he previously timed.

    0 讨论(0)
提交回复
热议问题