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

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

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毫秒?


当前回答

它们是一样的,因为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));

其他回答

这两个值相同的原因是因为您的长过程不需要那么长时间—不到一秒。你可以试着添加一个长循环(for (int i = 0;I < 100000000;i++);)在函数的末尾确保这是问题所在,然后我们可以从那里…

如果上面的情况是正确的,你将需要找到一个不同的系统函数(我知道你在linux上工作,所以我不能帮助你知道函数名称)来更准确地测量时间。我相信在linux中有一个类似于GetTickCount()的函数,你只需要找到它。

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

我通常使用以下方法:

#include <chrono>
#include <type_traits>

using perf_clock = std::conditional<
    std::chrono::high_resolution_clock::is_steady,
    std::chrono::high_resolution_clock,
    std::chrono::steady_clock
>::type;

using floating_seconds = std::chrono::duration<double>;

template<class F, class... Args>
floating_seconds run_test(Func&& func, Args&&... args)
{
   const auto t0 = perf_clock::now();
   std::forward<Func>(func)(std::forward<Args>(args)...);
   return floating_seconds(perf_clock::now() - t0);
} 

这与@nikos-athanasiou建议的相同,除了我避免使用非稳定时钟,并使用浮动秒数作为持续时间。

正如其他人已经注意到的,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>。这些计时器类也有不同版本,可以跨多个线程收集统计计时信息。还有一些方法允许您估计与两个立即连续的系统时钟查询相关的零错误。

我已经创建了一个类来自动测量流逝的时间,请检查代码(c++11)在这个链接:https://github.com/sonnt174/Common/blob/master/time_measure.h

使用timmeasure类的示例:

void test_time_measure(std::vector<int> arr) {
  TimeMeasure<chrono::microseconds> time_mea;  // create time measure obj
  std::sort(begin(arr), end(arr));
}