开发者

c++ get milliseconds since some date

开发者 https://www.devze.com 2023-01-08 11:17 出处:网络
I need some way in c++ to keep track of the number of milliseconds s开发者_如何学编程ince program execution.And I need the precision to be in milliseconds. (In my googling, I\'ve found lots of folks t

I need some way in c++ to keep track of the number of milliseconds s开发者_如何学编程ince program execution. And I need the precision to be in milliseconds. (In my googling, I've found lots of folks that said to include time.h and then multiply the output of time() by 1000 ... this won't work.)


clock has been suggested a number of times. This has two problems. First of all, it often doesn't have a resolution even close to a millisecond (10-20 ms is probably more common). Second, some implementations of it (e.g., Unix and similar) return CPU time, while others (E.g., Windows) return wall time.

You haven't really said whether you want wall time or CPU time, which makes it hard to give a really good answer. On Windows, you could use GetProcessTimes. That will give you the kernel and user CPU times directly. It will also tell you when the process was created, so if you want milliseconds of wall time since process creation, you can subtract the process creation time from the current time (GetSystemTime). QueryPerformanceCounter has also been mentioned. This has a few oddities of its own -- for example, in some implementations it retrieves time from the CPUs cycle counter, so its frequency varies when/if the CPU speed changes. Other implementations read from the motherboard's 1.024 MHz timer, which does not vary with the CPU speed (and the conditions under which each are used aren't entirely obvious).

On Unix, you can use GetTimeOfDay to just get the wall time with (at least the possibility of) relatively high precision. If you want time for a process, you can use times or getrusage (the latter is newer and gives more complete information that may also be more precise).

Bottom line: as I said in my comment, there's no way to get what you want portably. Since you haven't said whether you want CPU time or wall time, even for a specific system, there's not one right answer. The one you've "accepted" (clock()) has the virtue of being available on essentially any system, but what it returns also varies just about the most widely.


See std::clock()    


Include time.h, and then use the clock() function. It returns the number of clock ticks elapsed since the program was launched. Just divide it by "CLOCKS_PER_SEC" to obtain the number of seconds, you can then multiply by 1000 to obtain the number of milliseconds.


Some cross platform solution. This code was used for some kind of benchmarking:

#ifdef WIN32
  LARGE_INTEGER g_llFrequency = {0};
  BOOL g_bQueryResult = QueryPerformanceFrequency(&g_llFrequency);
#endif

//...

long long osQueryPerfomance()
{
#ifdef WIN32
  LARGE_INTEGER llPerf = {0};
  QueryPerformanceCounter(&llPerf);
  return llPerf.QuadPart * 1000ll / ( g_llFrequency.QuadPart / 1000ll);
#else
  struct timeval stTimeVal;
  gettimeofday(&stTimeVal, NULL);
  return stTimeVal.tv_sec * 1000000ll + stTimeVal.tv_usec;
#endif
}


The most portable way is using the clock function.It usually reports the time that your program has been using the processor, or an approximation thereof. Note however the following:

  • The resolution is not very good for GNU systems. That's really a pity.

  • Take care of casting everything to double before doing divisions and assignations.

  • The counter is held as a 32 bit number in GNU 32 bits, which can be pretty annoying for long-running programs.

There are alternatives using "wall time" which give better resolution, both in Windows and Linux. But as the libc manual states: If you're trying to optimize your program or measure its efficiency, it's very useful to know how much processor time it uses. For that, calendar time and elapsed times are useless because a process may spend time waiting for I/O or for other processes to use the CPU.


Here is a C++0x solution and an example why clock() might not do what you think it does.

#include <chrono>
#include <iostream>
#include <cstdlib>
#include <ctime>

int main()
{
   auto start1 = std::chrono::monotonic_clock::now();
   auto start2 = std::clock();

   sleep(1);

   for( int i=0; i<100000000; ++i);

   auto end1 = std::chrono::monotonic_clock::now();
   auto end2 = std::clock();

   auto delta1 = end1-start1;
   auto delta2 = end2-start2;

   std::cout << "chrono: " << std::chrono::duration_cast<std::chrono::duration<float>>(delta1).count() << std::endl;

   std::cout << "clock: " << static_cast<float>(delta2)/CLOCKS_PER_SEC << std::endl;
}

On my system this outputs:

chrono: 1.36839
clock: 0.36

You'll notice the clock() method is missing a second. An astute observer might also notice that clock() looks to have less resolution. On my system it's ticking by in 12 millisecond increments, terrible resolution.

If you are unable or unwilling to use C++0x, take a look at Boost.DateTime's ptime microsec_clock::universal_time().


This isn't C++ specific (nor portable), but you can do:

SYSTEMTIME systemDT;

In Windows.

From there, you can access each member of the systemDT struct.

You can record the time when the program started and compare the current time to the recorded time (systemDT versus systemDTtemp, for instance).

To refresh, you can call GetLocalTime(&systemDT);

To access each member, you would do systemDT.wHour, systemDT.wMinute, systemDT.wMilliseconds.

To get more information on SYSTEMTIME.


Do you want wall clock time, CPU time, or some other measurement? Also, what platform is this? There is no universally portable way to get more precision than time() and clock() give you, but...

  • on most Unix systems, you can use gettimeofday() and/or clock_gettime(), which give at least microsecond precision and access to a variety of timers;
  • I'm not nearly as familiar with Windows, but one of these functions probably does what you want.


You can try this code (get from StockFish chess engine source code (GPL)):

#include <iostream>
#include <stdio>

#if !defined(_WIN32) && !defined(_WIN64) // Linux - Unix
    #  include <sys/time.h>
    typedef timeval sys_time_t;
    inline void system_time(sys_time_t* t) {
        gettimeofday(t, NULL);
    }
    inline long long time_to_msec(const sys_time_t& t) {
        return t.tv_sec * 1000LL + t.tv_usec / 1000;
    }
    #else // Windows and MinGW
    #  include <sys/timeb.h>
    typedef _timeb sys_time_t;
    inline void system_time(sys_time_t* t) { _ftime(t); }
    inline long long time_to_msec(const sys_time_t& t) {
        return t.time * 1000LL + t.millitm;
    }
#endif

struct Time {
    void restart() { system_time(&t); }
    uint64_t msec() const { return time_to_msec(t); }
    long long elapsed() const {
        return long long(current_time().msec() - time_to_msec(t));
    }
    static Time current_time() { Time t; t.restart(); return t; }
private:
    sys_time_t t;
};

int main() {
    sys_time_t t;
    system_time(&t);
    long long currentTimeMs = time_to_msec(t);
    std::cout << "currentTimeMs:" << currentTimeMs << std::endl;

    Time time = Time::current_time();
    for (int i = 0; i < 1000000; i++) {
        //Do something
    }
    long long e = time.elapsed();
    std::cout << "time elapsed:" << e << std::endl;

    getchar();  // wait for keyboard input
}
0

精彩评论

暂无评论...
验证码 换一张
取 消