如何在C ++中计算时差


94

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

可接受的答案有效,但需要包含ctime或time.h(如注释中所述)。


Dupe,但现在无法链接
罗伯特·古尔德'2009年

2
结束投票的人数太少,为时已晚。我得到了一个有效的答案。不错的尝试。顺便说一句,我也找不到链接。
杰克·贝尼姆布尔

它的窗户?然后尝试GetTickCount(Windows API)
aJ。

5
罗伯特:幸运的是,因为新的帖子还提供了更多答案,我选择了其中一个。严重的是,我质疑关闭重复项的价值。如果第一个未提及某些解决方案怎么办?开发了新技术?标题不同,找不到它吗?
杰克·贝尼姆布尔

2
@JackBeNimble一直在接收一些并非完全是伪造的“ dups”(可能是那些可能很快阅读并标记该问题的人,因为它听起来与另一个问题相似),我非常同意你的观点...可能是元堆栈交换的一个点:o
code_fodder 2015年

Answers:


121

参见std::clock()功能。

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

如果要计算自身的执行时间(而不是用户的执行时间),则最好以时钟滴答(而不是秒)为单位。

编辑:
负责的头文件- <ctime><time.h>


4
请记住,即使clock()返回毫秒数,clock()的精度也可能比这差得多。Windows中的Fir实例,Clock()函数的精度约为40 ms。
John Dibling 09年

2
我在Mac 10.7上尝试过。我的应用程序在15秒内执行了100 mb的文件,但是比较时间报告为61秒。没什么用。我认为time()可能更好。
Miek 2013年

5
clock()返回程序消耗的CPU时间。因此,如果程序并行运行,则函数返回的时间将是所有CPU所用时间的累积,而不是经过的时间 cplusplus.com/reference/ctime/clock
Ameer Jewdaki

3
该答案具有误导性,因为它显示的是CPU时间,而不是实际的挂钟时间。
紫外线

1
我必须在这里同意Ultraviolet,使用CPU时间来衡量程序的速度似乎是错误的事情。OP应取消标记此为正确答案。IMO你应该使用std ::时辰:: steady_clock ::现在()作为在以下螺纹的多个答案中描述stackoverflow.com/questions/2808398/easily-measure-elapsed-time
arunsun

37

如果您使用的是c ++ 11,则这是一个简单的包装器(请参见this 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;
}

2
另一种选择是使用boost :: chrono而不是C ++ 11 STL std :: chrono命名空间。谢谢您的验证码。
Didac Perez Parera 2014年

注意:如果用户更改其时间Timer()和对elapsed()if 的呼叫之间的时间,则此方法将不起作用!std::chrono::high_resolution_clock::is_steady-在Linux上就是这种情况!
jhasse

30

我会认真考虑使用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';

3
但是boost local_time()不是单调的,因此不应用于测量时间流逝。我还没有找到从Boost访问单调时间的方法。
gatopeich 2011年

26

我添加了此答案以澄清接受的答案显示的CPU时间可能不是您想要的时间。因为根据参考,有CPU时间和挂钟时间。挂钟时间是显示实际经过时间的时间,而与其他进程共享的CPU等其他条件无关。例如,我使用多个处理器来完成某项任务,而CPU时间则高达18 ,而实际挂钟时间实际上为2秒

要获取您的实际时间,

#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();

2
没有这个答案,我将无法使用std :: chrono,谢谢!
giles

13

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";

7
同样,C ++ 11具有std::chrono几乎相同内容的名称空间。
ulidtko 2012年

12

在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;

}

8

您也可以使用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";
}

`


6

以防万一,如果您使用的是Unix,则可以使用它time来获取执行时间:

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

5

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


5

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

#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()是秒还是毫秒?
mkuse

4

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

要获得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毫秒。但这不是必需的,只要您关心的只是经过的时间即可。


4

如果您正在使用:

tstart = clock();

// ...do something...

tend = clock();

然后,您将需要以下内容来获取时间(以秒为单位):

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

0

对于intel 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;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.