【问题标题】:Timing algorithm: clock() vs time() in C++计时算法:C++ 中的clock() vs time()
【发布时间】:2012-09-01 20:33:35
【问题描述】:

对于一个算法的计时(大约以毫秒为单位),这两种方法哪个更好:

clock_t start = clock();
algorithm();
clock_t end = clock();
double time = (double) (end-start) / CLOCKS_PER_SEC * 1000.0;

或者,

time_t start = time(0);
algorithm();
time_t end = time(0);
double time = difftime(end, start) * 1000.0;

另外,从 Freenode 的 C++ 频道的一些讨论中,我知道时钟的分辨率非常差,因此对于(相对)快速算法而言,时间将为零。但是,哪个具有更好的分辨率 time() 或 clock()?还是一样?

【问题讨论】:

  • 您的 difftime 参数顺序错误

标签: c++ clock timing


【解决方案1】:

如果您使用 C++11,<chrono> 将是一个更好的库。

#include <iostream>
#include <chrono>
#include <thread>

void f()
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

int main()
{
    auto t1 = std::chrono::high_resolution_clock::now();
    f();
    auto t2 = std::chrono::high_resolution_clock::now();
    std::cout << "f() took "
              << std::chrono::duration_cast<std::chrono::milliseconds>(t2-t1).count()
              << " milliseconds\n";
}

示例取自here

【讨论】:

    【解决方案2】:

    这取决于您想要什么:time 测量实时,而clock 测量当前进程所花费的处理时间。如果您的进程休眠了相当长的时间,或者系统正忙于其他进程,则两者将大不相同。

    http://en.cppreference.com/w/cpp/chrono/c/clock

    【讨论】:

    • clock 也受本地并行性的影响。使用具有 N 个线程的 OpenMP 将导致所有 clock 返回值在并行区域期间(大约)增加 N 倍。
    【解决方案3】:

    time_t 结构可能是一个整数,这意味着它的分辨率为秒。

    第一段代码:它只会计算 CPU 做某事的时间,所以当你执行 sleep() 时,它不会计算任何东西。可以通过计算 sleep() 的时间来绕过它,但它可能会在一段时间后开始漂移。

    第二部分:只有秒的分辨率,如果您需要亚秒级时间读数,则不是很好。

    对于您可以获得的最佳分辨率的时间读数,您应该执行以下操作:

    double getUnixTime(void)
    {
        struct timespec tv;
    
        if(clock_gettime(CLOCK_REALTIME, &tv) != 0) return 0;
    
        return (tv.tv_sec + (tv.tv_nsec / 1000000000.0));
    }
    
    double start_time = getUnixTime();
    double stop_time, difference;
    
    doYourStuff();
    
    stop_time = getUnixTime();
    difference = stop_time - start_time;
    

    在大多数系统上,它的分辨率会低至几微秒,但它会因 CPU 不同而不同,甚至可能会因主要内核版本而异。

    【讨论】:

    • return 行中对double 的显式强制转换是多余的,因为两个算术运算符都对至少一个double 参数(文字,然后是除法的结果)进行操作。此外,您应该使用更简洁的文字符号:我认为return tv.tv_sec + tv.tv_nsec / 1.0e9; 更具可读性。
    • “所以当你做 sleep() 时,它不会计算任何东西”是真的吗?我测试了睡眠,它是按时钟计算的。
    【解决方案4】:

    &lt;chrono&gt; 是最好的。 Visual Studio 2013 提供了此功能。就个人而言,我已经尝试了上面提到的所有方法。我强烈建议您使用&lt;chrono&gt; 库。它可以跟踪挂墙时间,同时具有良好的分辨率(远小于一秒)。

    【讨论】:

      【解决方案5】:

      gettimeofday() 怎么样?当它被调用时,它会更新两个结构(timevaltimezone),以及时间信息。通常,传递timeval 结构就足够了,timezone 结构可以设置为NULL。更新后的timeval 结构将有两个成员tv_sectv_usectv_sec 是自 1970 年 1 月 1 日(Unix 纪元)00:00:00 以来的秒数,tv_usec 是额外的微秒数 w.r.t. tv_sec。因此,可以以非常好的分辨率来表达时间。

      可以这样使用:

      #include <time.h>
      
      struct timeval start_time;
      double mtime, seconds, useconds;
      gettimeofday(&start_time, NULL); //timeval is usually enough
      int seconds  = start_time.tv_sec; //time in seconds
      int useconds = start_time.tv_usec; //further time in microseconds
      int desired_time = seconds * 1000000 + useconds; //time in microseconds
      

      【讨论】:

        猜你喜欢
        • 2015-09-14
        • 1970-01-01
        • 1970-01-01
        • 2011-11-12
        • 2013-09-14
        • 2011-11-20
        • 2016-02-08
        • 1970-01-01
        相关资源
        最近更新 更多