测量C ++代码的运行时间?

时间:2012-06-16 10:57:41

标签: c++ linux

我想测量我的C ++代码的运行时间。执行我的代码大约需要12个小时,我想在执行代码时写下这段时间。我怎么能在我的代码中做到这一点?

操作系统:Linux

7 个答案:

答案 0 :(得分:73)

如果您使用的是C ++ 11,则可以使用system_clock::now()

auto start = std::chrono::system_clock::now();

/* do some work */

auto end = std::chrono::system_clock::now();
auto elapsed = end - start;
std::cout << elapsed.count() << '\n';

您还可以指定用于表示持续时间的粒度:

// this constructs a duration object using milliseconds
auto elapsed =
    std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

// this constructs a duration object using seconds
auto elapsed =
    std::chrono::duration_cast<std::chrono::seconds>(end - start);

如果您不能使用C ++ 11,请查看Boost中的chrono

使用这种标准库的最好的事情是它们的可移植性非常高(例如,它们都适用于Linux和Windows)。因此,如果您决定在之后移植您的应用程序,则无需担心太多。

这些库也遵循现代C ++设计,而不是类似C的方法。

编辑:以上示例可用于衡量wall-clock time。但是,这不是衡量程序执行时间的唯一方法。首先,我们可以区分用户和系统时间:

  • 用户时间:程序在user space中运行所花费的时间。
  • 系统时间:程序在系统(或内核)空间中运行所花费的时间。例如,在执行system call时,程序进入内核空间。

根据目标,可能需要或不将系统时间视为程序执行时间的一部分。例如,如果目标是仅测量用户代码上的编译器优化,那么最好省去系统时间。另一方面,如果用户想要确定系统调用是否是一个重要的开销,那么也需要测量系统时间。

此外,由于大多数现代系统是time-shared,因此不同的程序可能竞争若干计算资源(例如,CPU)。在这种情况下,可以进行另一种区分:

  • Wall-clock time通过使用挂钟时间,程序的执行方式与我们使用外部(墙上)时钟的方式相同。这种方法不考虑程序之间的相互作用。
  • CPU time在这种情况下,我们只计算程序在CPU上实际运行的时间。如果程序(P1)与另一个程序(P2)共同调度,并且我们想要获得P1的CPU时间,则此方法不包括P2运行时的时间且P1正在等待CPU(而不是挂钟时间方法)。

为了测量CPU时间,Boost包含set of extra clocks

  • process_real_cpu_clock,捕获当前进程花费的挂钟CPU时间。
  • process_user_cpu_clock,捕获当前进程花费的用户CPU时间。
  • process_system_cpu_clock,捕获当前进程花费的系统CPU时间。一个类似于元组的类process_cpu_clock,它可以一起捕获实际的,用户CPU和系统CPU处理时间。
  • thread_clock线程稳定时钟,给出当前线程花费的时间(当平台支持时)。

不幸的是,C ++ 11没有这样的时钟。但Boost是一个广泛使用的库,可能这些额外的时钟将在某些时候被整合到C ++ 1x中。因此,如果您使用Boost,您将在新的C ++标准添加它们时做好准备。

最后,如果要测量程序从命令行执行的时间(而不是在程序中添加一些代码),您可以查看time命令,就像@一样Bћовић建议。但是,这种方法不允许您测量程序的各个部分(例如,执行函数所需的时间)。

答案 1 :(得分:24)

使用std::chrono::steady_clock而非std::chrono::system_clock来衡量C ++ 11中的运行时间。原因是(引用system_clock的文档):

  

在大多数系统上,系统时间可以随时调整

虽然steady_clock是单调的,更适合测量间隔:

  

类std :: chrono :: steady_clock表示单调时钟。时间   物理时间向前移动时,此时钟的点数不会减少。   此时钟与挂钟时间无关,最适合   测量间隔。

以下是一个例子:

auto start = std::chrono::steady_clock::now();
// do something
auto finish = std::chrono::steady_clock::now();
double elapsed_seconds = std::chrono::duration_cast<
  std::chrono::duration<double> >(finish - start).count();

一个小实用提示:如果您正在测量运行时间并希望报告秒std::chrono::duration_cast<std::chrono::seconds>很少是您需要的,因为它会为您提供整个秒数。以double为例,以秒为单位获取时间。

答案 2 :(得分:10)

您可以使用time启动您的计划。当它结束时,它会打印关于程序运行的美好时间统计信息。可以轻松配置要打印的内容。默认情况下,它会打印执行程序所花费的用户和CPU时间。

编辑:请注意代码中的每个度量都不正确,因为您的应用程序将被其他程序阻止,因此会给您错误的值 * 。< / p>

* 由于错误的值,我的意思是很容易获得执行程序所花费的时间,但是这个时间会因程序执行期间的CPU负载而异。为了获得相对稳定的时间测量,不依赖于CPU负载,可以使用time执行应用程序并使用CPU作为测量结果。

答案 3 :(得分:9)

我在我的一个项目中使用了类似的东西:

#include <sys/time.h>

struct timeval start, end;
gettimeofday(&start, NULL);
//Compute
gettimeofday(&end, NULL);
double elapsed = ((end.tv_sec - start.tv_sec) * 1000) 
        + (end.tv_usec / 1000 - start.tv_usec / 1000);

这是毫秒,它适用于C和C ++。

答案 4 :(得分:2)

如果您希望使用printf()打印测量的时间,可以使用以下方法:

auto start = std::chrono::system_clock::now();
/* measured work */
auto end = std::chrono::system_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
printf("Time = %lld ms\n", static_cast<long long int>(elapsed.count()));

答案 5 :(得分:0)

您还可以尝试一些自动启动和停止的计时器类,并收集有关在任何代码块中花费的平均时间,最长和最短时间以及调用次数的统计信息。这些cxx-rtimer类可在GitHub上获得,并支持使用std :: chrono,clock_gettime()或boost :: posix_time作为后端时钟源。

使用这些计时器,您可以执行以下操作:

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

在程序完成时将时间统计信息写入std :: cerr。

答案 6 :(得分:0)

这是我使用的代码:

  const auto start = std::chrono::steady_clock::now();

  // Your code here.

  const auto end = std::chrono::steady_clock::now();
  std::chrono::duration<double> elapsed = end - start;
  std::cout << "Time in seconds: " << elapsed.count() << '\n';

您不想使用std::chrono::system_clock,因为它不是单调的!如果用户在代码中间更改时间,则结果将是错误的-甚至可能是负数。 std::chrono::high_resolution_clock可以使用std::chrono::system_clock来实现,因此我也不建议这样做。

此代码还避免了丑陋的转换。