我试图使用时间()来测量我的程序的各个点。

我不明白的是为什么前后的值是一样的?我知道这不是分析我的程序的最佳方式,我只是想看看需要多长时间。

printf("**MyProgram::before time= %ld\n", time(NULL));

doSomthing();
doSomthingLong();

printf("**MyProgram::after time= %ld\n", time(NULL));

我试过:

struct timeval diff, startTV, endTV;

gettimeofday(&startTV, NULL); 

doSomething();
doSomethingLong();

gettimeofday(&endTV, NULL); 

timersub(&endTV, &startTV, &diff);

printf("**time taken = %ld %ld\n", diff.tv_sec, diff.tv_usec);

我如何读取**时间花费= 0 26339的结果?这是否意味着26339纳秒= 26.3毫秒?

**时间= 4 45025,这是否意味着4秒25毫秒?


当前回答

//***C++11 Style:***
#include <chrono>

std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();

std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << "[µs]" << std::endl;
std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::nanoseconds> (end - begin).count() << "[ns]" << std::endl;

其他回答

正如其他人已经注意到的,C标准库中的time()函数的分辨率不超过1秒。唯一可以提供更好分辨率的完全可移植的C函数似乎是clock(),但它测量的是处理器时间而不是wallclock时间。如果一个人满足于将自己局限于POSIX平台(例如Linux),那么clock_gettime()函数是一个很好的选择。

从c++ 11开始,就有了更好的计时工具,以一种可以在不同编译器和操作系统间移植的形式提供了更好的分辨率。类似地,boost::datetime库提供了良好的高分辨率计时类,这些类应该是高度可移植的。

One challenge in using any of these facilities is the time-delay introduced by querying the system clock. From experimenting with clock_gettime(), boost::datetime and std::chrono, this delay can easily be a matter of microseconds. So, when measuring the duration of any part of your code, you need to allow for there being a measurement error of around this size, or try to correct for that zero-error in some way. Ideally, you may well want to gather multiple measurements of the time taken by your function, and compute the average, or maximum/minimum time taken across many runs.

为了帮助解决所有这些可移植性和统计数据收集问题,我一直在Github上开发cxx-rtimers库,它试图为c++代码的计时块提供一个简单的API,计算零错误,并从代码中嵌入的多个计时器报告统计数据。如果你有一个c++ 11编译器,你只需简单地#include <rtimers/cxx11.hpp>,并使用如下代码:

void expensiveFunction() {
    static rtimers::cxx11::DefaultTimer timer("expensiveFunc");
    auto scopedStartStop = timer.scopedStart();
    // Do something costly...
}

在程序退出时,你会得到一个写入std::cerr的时间统计摘要,例如:

Timer(expensiveFunc): <t> = 6.65289us, std = 3.91685us, 3.842us <= t <= 63.257us (n=731)

它显示了平均时间,它的标准偏差,上限和下限,以及这个函数被调用的次数。

如果你想使用特定于linux的计时函数,你可以#include <rtimers/posix.hpp>,或者如果你有Boost库但是一个旧的c++编译器,你可以#include <rtimers/ Boost .hpp>。这些计时器类也有不同版本,可以跨多个线程收集统计计时信息。还有一些方法允许您估计与两个立即连续的系统时钟查询相关的零错误。

在linux上,clock_gettime()是一个很好的选择。 必须链接实时库(-lrt)。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

#define BILLION  1000000000L;

int main( int argc, char **argv )
  {
    struct timespec start, stop;
    double accum;

    if( clock_gettime( CLOCK_REALTIME, &start) == -1 ) {
      perror( "clock gettime" );
      exit( EXIT_FAILURE );
    }

    system( argv[1] );

    if( clock_gettime( CLOCK_REALTIME, &stop) == -1 ) {
      perror( "clock gettime" );
      exit( EXIT_FAILURE );
    }

    accum = ( stop.tv_sec - start.tv_sec )
          + ( stop.tv_nsec - start.tv_nsec )
            / BILLION;
    printf( "%lf\n", accum );
    return( EXIT_SUCCESS );
  }

它们是一样的,因为doSomething函数发生得比计时器的粒度快。试一试:

printf ("**MyProgram::before time= %ld\n", time(NULL));

for(i = 0; i < 1000; ++i) {
    doSomthing();
    doSomthingLong();
}

printf ("**MyProgram::after time= %ld\n", time(NULL));

time(NULL)函数调用将返回自epoc: 1970年1月1日以来经过的秒数。也许你要做的是取两个时间戳的差值:

size_t start = time(NULL);
doSomthing();
doSomthingLong();

printf ("**MyProgram::time elapsed= %lds\n", time(NULL) - start);

第二个程序打印的值是秒和微秒。

0 26339 = 0.026'339 s =   26339 µs
4 45025 = 4.045'025 s = 4045025 µs