如何在 C++ 中获取一段代码的执行时间?

Posted

技术标签:

【中文标题】如何在 C++ 中获取一段代码的执行时间?【英文标题】:How to get execution time of a piece of code in C++? 【发布时间】:2014-07-03 18:31:23 【问题描述】:

我正在尝试对一段代码进行基准测试。它基于此代码here,有趣的部分基本上如下所示:

    auto t0 = std::chrono::high_resolution_clock::now();
    ...
    auto t1 = std::chrono::high_resolution_clock::now();
    std::cout << secs(t1-t0).count() << " s\n";

问题是我在共享机器上,这给了我时间,所以我的结果没有给我任何一致的东西。我真正需要的是某种秒表工具,它可以让我得到我的代码运行的时间,而不是墙上的时间。有哪些选择?如果涉及到系统特定的调用,我在 Linux 机器上,但如果可能的话,我宁愿保持这段代码可移植。

我查看了其他问题,例如 this 和 this,但它们似乎都提供了挂时解决方案。

【问题讨论】:

您是否考虑过隔离main 中的代码,并通过time 进行编译和运行? (不是测量小段代码的最佳选择,但由于您使用的是秒数,我认为这应该足够好了) 我可以在万不得已的情况下这样做,但是我正在使用大量配置运行大量测试,如果我必须继续复制到 main 中,则此测试将花费更长的时间并且会不那么愉快 当你说“时间”时,你是指CPU时间吗?如果您要排除所有其他进程对 CPU 的使用,您是否希望时间包括 i/o? 在这种特殊情况下没有 I/O 时间。它只是一小段代码,用于测试具有不同算法和不同输入的无序地图的行为。 我期待看到一些提及 gprof 和 gcc 标志以使其工作。为什么不为此使用分析器?请参阅***.com/questions/21072058/… 之类的问题。 【参考方案1】:

如果在您的操作系统上可用,您可以使用times API 获得与内置time 命令类似的结果。

#include <sys/times.h>
...
struct tms  start, end;
times(&start);
//Do command
times(&end);
clock_t usr_time = end->tms_utime - start->tms_utime;
clock_t sys_time = end->tms_stime - start->tms_stime;

要 100% 完成,您应该检查时间的结果是否不等于 -1,否则检查 errno 代码。

【讨论】:

答案中有错字。 startend 不是指针,所以计算应该是 clock_t usr_time = end.tms_utime - start.tms_utime;clock_t sys_time = end.tms_stime - start.tms_stime; 另外,times() 返回的单位是CLOCKS_PER_SEC 中经过的刻度数。所以要获得经过时间的秒数,请执行(double) usr_time / CLOCKS_PER_SEC(我认为)。 Kilian 请花时间更正上面的错字。【参考方案2】:

适用于 Linux

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

  double  theseSecs = 0.0;
  double  startSecs = 0.0;
  double  secs;
  double  CPUsecs = 0.0;
  double  CPUutilisation = 0.0;
  double  answer = 0;
  clock_t starts;

  void start_CPU_time()
        
      starts = clock();;
      return;
  

  void end_CPU_time()
  
      CPUsecs = (double)(clock() - starts)/(double)CLOCKS_PER_SEC;
      return;
      

  struct timespec tp1;
  void getSecs()
  
     clock_gettime(CLOCK_REALTIME, &tp1);
     theseSecs =  tp1.tv_sec + tp1.tv_nsec / 1e9;           
     return;
  

  void start_time()
  
      getSecs();
      startSecs = theseSecs;
      return;
  

  void end_time()
  
      getSecs();
      secs    = theseSecs - startSecs;
      return;
      

  void calculate()
  
      int i, j;
      for (i=1; i<100001; i++)
      
          for (j=1; j<10001; j++)
          
              answer = answer + (float)i / 100000000.0;
          
      
  

 void main()
 
     start_time();
     start_CPU_time();
     calculate();
     end_time();
     end_CPU_time();
     CPUutilisation = CPUsecs /  secs * 100.0;
     printf("\n Answer %10.1f, Elapsed Time %7.4f, CPU Time %7.4f, CPU Ut %3.0f%\n",
              answer, secs, CPUsecs, CPUutilisation);  
 

【讨论】:

【参考方案3】:

理想情况下,正如您问题下的评论所提到的,您应该隔离您尝试在 main 中测量的代码段,并仅使用 unix time 命令行工具,该工具报告 usersystem时间。

如果您无法做到这一点,请考虑查看source code 的time 并可能使用相同的技术对您的代码进行基准测试。

【讨论】:

【参考方案4】:

我认为您需要将clock_gettime() 与以下时钟CLOCK_PROCESS_CPUTIME_IDCLOCK_THREAD_CPUTIME_ID 一起使用。它们给出了进程/线程消耗的 CPU 时间。

CLOCK_PROCESS_CPUTIME_ID
  High-resolution per-process timer from the CPU.
CLOCK_THREAD_CPUTIME_ID
  Thread-specific CPU-time clock.

参考:

http://linux.die.net/man/3/clock_gettime Understanding the different clocks of clock_gettime() http://www.guyrutenberg.com/2007/09/22/profiling-code-using-clock_gettime/

我认为给出merlin2011 的建议在许多情况下是不可行的,因为隔离可能需要付出很多努力,而使用clock_gettime() 添加两行代码非常实用。您甚至可以将对 clock_gettime() 的调用封装在一个类中。

【讨论】:

以上是关于如何在 C++ 中获取一段代码的执行时间?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 函数 Sleep() 在一段代码之前执行

如何在 Windows ( C++ ) 中创建进程以运行另一段代码?

在Python3中,socket.recv方法如果一段时间内没有收到返回,如何让这段代码跳过,并执行下一步操作

预先设置 C++ 代码的执行时间

C++语言怎么在main函数执行之前执行一段代码

定时执行语句 - C++ [重复]