c ++从某个日期开始获得毫秒数

时间:2010-07-19 18:16:27

标签: c++ time

我需要在c ++中使用某种方法来跟踪自程序执行以来的毫秒数。我需要精确度以毫秒为单位。 (在我的谷歌搜索中,我发现许多人说包括time.h然后将time()的输出乘以1000 ......这不起作用。)

9 个答案:

答案 0 :(得分:8)

已多次提出

clock。这有两个问题。首先,它通常没有甚至接近毫秒的分辨率(10-20毫秒可能更常见)。其次,它的一些实现(例如,Unix和类似的)返回CPU时间,而其他(例如,Windows)返回挂起时间。

你还没有真正说过你是想要壁挂时间还是CPU时间,这很难给出一个非常好的答案。在Windows上,您可以使用GetProcessTimes。这将直接为您提供内核和用户CPU时间。它还会告诉您创建进程的时间,因此如果您想要创建进程后的毫秒数,那么您可以从当前时间(GetSystemTime)中减去进程创建时间。还提到了QueryPerformanceCounter。这有一些奇怪之处 - 例如,在某些实现中,它从CPU循环计数器中检索时间,因此当CPU速度发生变化时,其频率会发生变化。其他实现从主板的1.024 MHz定时器读取,其随CPU速度而变化(并且每个使用的条件并不完全明显)。

在Unix上,您可以使用GetTimeOfDay来获得相对较高精度的(至少可能性)。如果您想要一个流程的时间,可以使用timesgetrusage(后者更新,并提供更完整的信息,也可能更精确)。

结论:正如我在评论中所说,没有办法得到你想要的东西。既然你还没有说过你是想要CPU时间还是壁挂时间,即使对于特定的系统,也没有一个正确的答案。你已经“接受”的那个(clock())具有在任何系统上可用的优点,但它返回的内容也变化最大。

答案 1 :(得分:1)

请参阅std::clock()

答案 2 :(得分:1)

包含time.h,然后使用clock()函数。它返回自程序启动以来经过的时钟周期数。只需将它除以“CLOCKS_PER_SEC”以获得秒数,然后可以乘以1000以获得毫秒数。

答案 3 :(得分:1)

一些跨平台的解决方案。此代码用于某种基准测试:

#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
}

答案 4 :(得分:1)

最便携的方式是使用 clock 功能。它通常会报告程序使用处理器的时间或其近似值。但请注意以下内容:

  • 对于GNU系统,分辨率不是很好。真的很可惜。

  • 在进行分割和分配之前,请注意将所有内容都转换为 double

  • 计数器在GNU 32位中保持为32位数,这对于长时间运行的程序来说非常烦人。

在Windows和Linux中,使用“壁挂时间”可以提供更好的分辨率。但正如libc手册所述:如果您正在尝试优化程序或测量其效率,那么了解它使用的处理器时间非常有用。为此,日历时间和已用时间是无用的,因为进程可能花费时间等待I / O或其他进程使用CPU。

答案 5 :(得分:1)

这是一个C ++ 0x解决方案,以及为什么clock()可能无法按照您的想法执行操作的示例。

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

在我的系统上输出:

chrono: 1.36839
clock: 0.36

您会注意到clock()方法缺少一秒钟。精明的观察者也可能会注意到clock()看起来分辨率较低。在我的系统上,它以 12毫秒增量,可怕的分辨率滴答作响。

如果您不能或不愿意使用C ++ 0x,请查看Boost.DateTimeptime microsec_clock::universal_time()

答案 6 :(得分:0)

这不是C ++特定的(也不是可移植的),但你可以这样做:

SYSTEMTIME systemDT;

在Windows中。

从那里,您可以访问systemDT struct的每个成员。

您可以记录程序开始的时间,并将当前时间与记录的时间进行比较(例如systemDTsystemDTtemp)。

要刷新,您可以拨打GetLocalTime(&systemDT);

要访问每个成员,您可以执行systemDT.wHoursystemDT.wMinutesystemDT.wMilliseconds

获取有关SYSTEMTIME的更多信息。

答案 7 :(得分:0)

您想要挂钟时间,CPU时间或其他一些测量吗?这个平台是什么?没有普遍可移植的方法来获得比time()clock()给你更精确的方法,但是......

  • 在大多数Unix系统上,您可以使用gettimeofday()和/或clock_gettime(),它们提供至少微秒的精度并可以访问各种计时器;
  • 我对Windows并不熟悉,但these functions中的一个可能会做你想要的。

答案 8 :(得分:0)

您可以尝试此代码(从StockFish国际象棋引擎源代码(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
}