提升:获取函数运行时间的秒/毫/微/纳米

时间:2015-10-29 03:02:54

标签: c++ boost

我基本上有一个学校项目测试不同排序算法的时间,并记录他们花费多长时间来排序n个数字。所以我决定使用带有c ++的Boost库来记录时间。我在这一点上我不知道该怎么做,我用Google搜索并发现人们使用不同的方式。例如

auto start = boost::chrono::high_resolution_clock::now();
auto end = boost::chrono::high_resolution_clock::now();
auto time = (end-start).count();

boost::chrono::system_clock::now();

boost::chrono::steady_clock::now() 

甚至使用类似的东西

boost::timer::cpu_timer and boost::timer::auto_cpu_time

boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time( );

所以我想确定现在如何做到这就是我所拥有的

typedef boost::chrono::duration<double, boost::nano> boost_nano;

auto start_t = boost::chrono::high_resolution_clock::now();
// call function
auto end_t = boost::chrono::high_resolution_clock::now();
boost_nano time = (end_t - start_t);
cout << t.count();

我正走在正确的轨道上吗?

3 个答案:

答案 0 :(得分:1)

你可能想要高分辨率计时器。

您可以使用boost::chronostd::chrono

Boost Chrono对IO内置有一些支持,因此它更容易以人性化的方式报告时间。

我通常使用类似于此的包装器:

template <typename Caption, typename F>
auto timed(Caption const& task, F&& f) {
    using namespace boost::chrono;
    struct _ {
        high_resolution_clock::time_point s;
        Caption const& task;
        ~_() { std::cout << " -- (" << task << " completed in " << duration_cast<milliseconds>(high_resolution_clock::now() - s) << ")\n"; }
    } timing { high_resolution_clock::now(), task };

    return f();
}

报告所用的时间(以毫秒为单位)。

这里的好处是你可以及时建造和类似的:

std::vector<int> large = timed("generate data", [] {
           return generate_uniform_random_data(); });

但是,通用代码块:

timed("do_step2", [] {
    // step two is foo and bar:
    foo();
    bar();
});

如果可以的话foo()抛出,就好了。

样本

<强> Live On Coliru

int main() {
    return timed("demo task", [] {
        sleep(1);
        return 42; 
    });
}

打印

 -- (demo task completed in 1000 milliseconds)
42

答案 1 :(得分:0)

使用std::chrono::steady_clockstd::chrono::high_resolution_clock(如果它是稳定的 - 见下文)而不是std::chrono::system_clock来测量C ++ 11中的运行时间(或使用其等效的提升)。原因是(引用<img src="../client/app/public/genolagana.jpg" alt="Profile Picture" height="42" width="42"> 的文档):

  

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

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

  

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

以下是一个例子:

system_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>为例,以秒为单位获取时间。

正如Gregor McGregor建议的那样,你可以使用double,它有时可以提供更高的分辨率(虽然它可以是high_resolution_clock的别名),但要注意它也可能是{的别名{1}},因此您可能需要查看steady_clock

答案 2 :(得分:0)

我通常使用时间(0)来控制循环的持续时间。 time(0)只是一次性测量,由于其持续时间短,对其他所有事情的影响最小(您甚至可以运行无操作循环来捕获从任何其他循环测量工作中减去多少)。

因此,在循环运行3(或10秒)的循环中,循环可以调用您尝试测量的东西多少次?

以下是我的旧代码如何衡量'getpid()'

持续时间的示例
uint32_t spinPidTillTime0SecChange(volatile int& pid)
{
   uint32_t spinCount = 1; // getpid() invocation count

   // no measurement, just spinning
   ::time_t tStart = ::time(nullptr);
   ::time_t   tEnd = tStart;

   while (0 == (tEnd - tStart)) // (tStart == tEnd)
   {
      pid = ::getpid();
      tEnd = ::time(nullptr);
      spinCount += 1;
   }
   return(spinCount);
}

调用此3(或10)次,将返回值一起添加。为了方便起见,丢弃第一次测量(因为它可能是第二次测量)。

是的,我确信有一个访问时间(0)访问的c ++ 11版本。