【问题标题】:How to calculate a time difference in C++如何在 C++ 中计算时间差
【发布时间】:2009-04-08 00:14:18
【问题描述】:

在 C++ 中计算时间差的最佳方法是什么?我正在计时程序的执行速度,所以我对毫秒感兴趣。更好的是,秒.毫秒..

接受的答案有效,但需要包含 ctime 或 time.h,如 cmets 中所述。

【问题讨论】:

  • 复制,但现在无法链接
  • 结束投票太少,太晚了。我得到了一个有效的答案。不错的尝试。顺便说一句,我也找不到链接。
  • 它适用于 Windows?然后尝试 GetTickCount (Windows API)
  • 罗伯特:幸运的是,因为新帖子允许更多答案,我选择了其中一个。说真的,我质疑关闭一个重复帖子的价值。如果第一个解决方案没有提到怎么办?新技术开发了吗?标题不同没找到?
  • @JackBeNimble 已经接受了一些不完全是 dups 的“dups”(也许那些可能很快阅读问题并标记它的人,因为它听起来与另一个问题相似),我非常同意你的观点......可能是元堆栈交换的一点:o

标签: c++


【解决方案1】:

std::clock()函数。

const clock_t begin_time = clock();
// do something
std::cout << float( clock () - begin_time ) /  CLOCKS_PER_SEC;

如果您想计算自己的执行时间(而不是用户),最好在时钟滴答(而不是秒)中执行此操作。

编辑:
负责的头文件 - &lt;ctime&gt;&lt;time.h&gt;

【讨论】:

  • 请记住,即使 clock() 返回毫秒数,clock() 的精度也可能比这差得多。在 Windows 中的 Fir 实例中,clock() 函数的精度大约为 40 毫秒。
  • 我在 Mac 10.7 上试过这个。我的应用程序在 15 秒内执行了一个 100 mb 的文件,但差异时间报告为 61 秒。没多大用处。我认为 time() 可能更好。
  • clock() 返回程序消耗的 CPU 时间。因此,如果程序并行运行,则函数返回的时间将是所有 CPU 上花费的时间的累积,而不是经过的时间cplusplus.com/reference/ctime/clock
  • 这个答案具有误导性,因为它显示的是 CPU 时间,而不是实际的挂钟时间。
  • 我必须同意 Ultraviolet 的观点,使用 CPU 时间来衡量程序的速度似乎是错误的做法。 OP 应将此取消标记为正确答案。 IMO,您应该使用 std::chrono::steady_clock::now() ,如以下线程stackoverflow.com/questions/2808398/easily-measure-elapsed-time 中的多个答案所述
【解决方案2】:

我添加了这个答案以澄清接受的answer 显示的 CPU 时间可能不是您想要的时间。因为根据the reference,有CPU时间和挂钟时间。挂钟时间是显示实际经过时间的时间,无论其他条件如何,例如其他进程共享的 CPU。例如,我使用多个处理器执行某项任务,CPU 时间很高 18s,而实际挂钟时间实际上需要 2s

要获得你做的实际时间,

#include <chrono>

auto t_start = std::chrono::high_resolution_clock::now();
// the work...
auto t_end = std::chrono::high_resolution_clock::now();

double elapsed_time_ms = std::chrono::duration<double, std::milli>(t_end-t_start).count();

【讨论】:

  • 如果没有这个答案,我将无法使用 std::chrono,谢谢!
  • 注意这是假设系统时钟没有改变。如果您正在编写代码来处理所有需要考虑的情况,则需要考虑夏令时、闰秒、与 NTP 的时间同步等。
【解决方案3】:

如果您使用的是 c++11,这里有一个简单的包装器(参见 gist):

#include <iostream>
#include <chrono>

class Timer
{
public:
    Timer() : beg_(clock_::now()) {}
    void reset() { beg_ = clock_::now(); }
    double elapsed() const { 
        return std::chrono::duration_cast<second_>
            (clock_::now() - beg_).count(); }

private:
    typedef std::chrono::high_resolution_clock clock_;
    typedef std::chrono::duration<double, std::ratio<1> > second_;
    std::chrono::time_point<clock_> beg_;
};

或者对于 *nix 上的 c++03:

#include <iostream>
#include <ctime>

class Timer
{
public:
    Timer() { clock_gettime(CLOCK_REALTIME, &beg_); }

    double elapsed() {
        clock_gettime(CLOCK_REALTIME, &end_);
        return end_.tv_sec - beg_.tv_sec +
            (end_.tv_nsec - beg_.tv_nsec) / 1000000000.;
    }

    void reset() { clock_gettime(CLOCK_REALTIME, &beg_); }

private:
    timespec beg_, end_;
};

使用示例:

int main()
{
    Timer tmr;
    double t = tmr.elapsed();
    std::cout << t << std::endl;

    tmr.reset();
    t = tmr.elapsed();
    std::cout << t << std::endl;
    return 0;
}

【讨论】:

  • 另一种选择是使用 boost::chrono 而不是 C++11 STL std::chrono 命名空间。谢谢你的代码。
  • 小心:如果用户在Timer()elapsed() 之间更改时间(如果!std::chrono::high_resolution_clock::is_steady),这将不起作用——Linux 上就是这种情况!
【解决方案4】:

我会认真考虑使用 Boost,尤其是 boost::posix_time::ptime 和 boost::posix_time::time_duration(http://www.boost.org/doc/libs/1_38_0/doc/html/date_time/posix_time.html)。

它是跨平台的、易于使用的,并且根据我的经验,它提供了操作系统提供的最高级别的时间分辨率。可能也很重要;它提供了一些非常好的 IO 操作符。

要使用它来计算程序执行的差异(以微秒计;可能有点矫枉过正),它看起来像这样 [浏览器编写,未测试]:

ptime time_start(microsec_clock::local_time());
//... execution goes here ...
ptime time_end(microsec_clock::local_time());
time_duration duration(time_end - time_start);
cout << duration << '\n';

【讨论】:

  • 但是 boost local_time() 不是单调的,所以它不应该被用来测量时间流逝。我还没有找到从 Boost 访问单调时间的方法。
【解决方案5】:

boost 1.46.0 及更高版本包括 Chrono 库:

thread_clock 类提供对真正线程挂钟的访问,即 调用线程的实际 CPU 时间时钟。线程相对 当前时间可以通过调用thread_clock::now()获取

#include <boost/chrono/thread_clock.hpp>
{
...
    using namespace boost::chrono;
    thread_clock::time_point start = thread_clock::now();
    ...
    thread_clock::time_point stop = thread_clock::now();  
    std::cout << "duration: " << duration_cast<milliseconds>(stop - start).count() << " ms\n";

【讨论】:

  • 另外,C++11std::chrono 命名空间,内容几乎相同。
【解决方案6】:

在 Windows 中:使用 GetTickCount

//GetTickCount defintition
#include <windows.h>
int main()
{

    DWORD dw1 = GetTickCount();

    //Do something 

    DWORD dw2 = GetTickCount();

    cout<<"Time difference is "<<(dw2-dw1)<<" milliSeconds"<<endl;

}

【讨论】:

  • 如果程序运行很长时间,请注意翻转:DWORD 是 32 位无符号的,并且会在 2^32 毫秒(大约 49.71 天)时从 0xFFFFFFFF 翻转到 0x00000000。显示的模式 (currentTime - startTime) 是正确的(前提是保证时间差不超过 2^32-1 毫秒)。
  • 我永远不会使用 GetTickCount,因为它在 50 天后无效,请使用 GetTickCount64
【解决方案7】:

您也可以使用clock_gettime。该方法可用于测量:

  1. 系统范围的实时时钟
  2. 系统范围的单调时钟
  3. 每进程 CPU 时间
  4. 每进程线程 CPU 时间

代码如下:

#include < time.h >
#include <iostream>
int main(){
  timespec ts_beg, ts_end;
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts_beg);
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts_end);
  std::cout << (ts_end.tv_sec - ts_beg.tv_sec) + (ts_end.tv_nsec - ts_beg.tv_nsec) / 1e9 << " sec";
}

`

【讨论】:

    【解决方案8】:

    如果你在 Unix 上,你可以使用time 来获取执行时间:

    $ g++ myprog.cpp -o myprog
    $ time ./myprog
    

    【讨论】:

      【解决方案9】:

      对我来说,最简单的方法是:

      #include <boost/timer.hpp>
      
      boost::timer t;
      double duration;
      
      t.restart();
      /* DO SOMETHING HERE... */
      duration = t.elapsed();
      
      t.restart();
      /* DO OTHER STUFF HERE... */
      duration = t.elapsed();
      

      使用这段代码你不必做经典的end - start

      享受你最喜欢的方法。

      【讨论】:

      • t.elapsed() 是秒还是毫秒?
      【解决方案10】:

      附带说明:如果您在 Windows 上运行,并且确实需要精确度,则可以使用 QueryPerformanceCounter。它为您提供(可能)纳米秒的时间。

      【讨论】:

        【解决方案11】:

        在开始和结束时以毫秒为单位获取系统时间,然后减去。

        要在 POSIX 中获取自 1970 年以来的毫秒数,您可以编写:

        struct timeval tv;
        
        gettimeofday(&tv, NULL);
        return ((((unsigned long long)tv.tv_sec) * 1000) +
                (((unsigned long long)tv.tv_usec) / 1000));
        

        要在 Windows 上获取自 1601 以来的毫秒数,您可以编写:

        SYSTEMTIME systime;
        FILETIME filetime;
        
        GetSystemTime(&systime);
        if (!SystemTimeToFileTime(&systime, &filetime))
            return 0;
        
        unsigned long long ns_since_1601;
        ULARGE_INTEGER* ptr = (ULARGE_INTEGER*)&ns_since_1601;
        
        // copy the result into the ULARGE_INTEGER; this is actually
        // copying the result into the ns_since_1601 unsigned long long.
        ptr->u.LowPart = filetime.dwLowDateTime;
        ptr->u.HighPart = filetime.dwHighDateTime;
        
        // Compute the number of milliseconds since 1601; we have to
        // divide by 10,000, since the current value is the number of 100ns
        // intervals since 1601, not ms.
        return (ns_since_1601 / 10000);
        

        如果您希望将 Windows 答案标准化,以便它还返回自 1970 年以来的毫秒数,那么您必须将答案调整 11644473600000 毫秒。但是,如果您只关心经过的时间,那就没有必要了。

        【讨论】:

          【解决方案12】:

          如果您正在使用:

          tstart = clock();
          
          // ...do something...
          
          tend = clock();
          

          那么您将需要以下内容来获得以秒为单位的时间:

          time = (tend - tstart) / (double) CLOCKS_PER_SEC;
          

          【讨论】:

            【解决方案13】:

            这似乎适用于英特尔 Mac 10.7:

            #include <time.h>
            
            time_t start = time(NULL);
            
            
                //Do your work
            
            
            time_t end = time(NULL);
            std::cout<<"Execution Time: "<< (double)(end-start)<<" Seconds"<<std::endl;
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-02-02
              • 1970-01-01
              • 2021-10-20
              • 1970-01-01
              • 1970-01-01
              • 2017-01-14
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多