C++ boost timer

boost库中的timer类能够为程序员提供毫秒级别的操作精度和操作函数,它是一个小型的计时器,可以用来测量时间的流逝。

timer类位于boost命名空间下,使用时需要包含头文件:#include <boost\timer.hpp>
下面是timer使用示例:

timer _timer;

    cout << "可度量的最大时间(s):" << _timer.elapsed_max() << endl;

    cout << "可度量的最小时间(s):" << _timer.elapsed_min() << endl;

    cout << "已经流逝的时间(s):" << _timer.elapsed() << endl;

输出可以参考下面的结果:

可度量的最大时间:2.14748e+06
可度量的最小时间:0.001
已经流逝的时间:0.195

由于机器的不同,其中elapsed_max()返回的结果也不同,这一点相信大家都有所了解,这里的结果仅供参考。

timer类是很短小精悍的一个类,它的代码行数很少,而且加上构造函数也就五个函数。这里贴出它的源码:

//  boost timer.hpp header file  ---------------------------------------------//

//  Copyright Beman Dawes 1994-99.  Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/timer for documentation.

//  Revision History
//  01 Apr 01  Modified to use new <boost/limits.hpp> header. (JMaddock)
//  12 Jan 01  Change to inline implementation to allow use without library
//             builds. See docs for more rationale. (Beman Dawes) 
//  25 Sep 99  elapsed_max() and elapsed_min() added (John Maddock)
//  16 Jul 99  Second beta
//   6 Jul 99  Initial boost version

#ifndef BOOST_TIMER_HPP
#define BOOST_TIMER_HPP

#include <boost/config.hpp>
#include <ctime>
#include <boost/limits.hpp>

# ifdef BOOST_NO_STDC_NAMESPACE
    namespace std { using ::clock_t; using ::clock; }
# endif


namespace boost {

//  timer  -------------------------------------------------------------------//

//  A timer object measures elapsed time.

//  It is recommended that implementations measure wall clock rather than CPU
//  time since the intended use is performance measurement on systems where
//  total elapsed time is more important than just process or CPU time.

//  Warnings: The maximum measurable elapsed time may well be only 596.5+ hours
//  due to implementation limitations.  The accuracy of timings depends on the
//  accuracy of timing information provided by the underlying platform, and
//  this varies a great deal from platform to platform.

class timer
{
 public:
         timer() { _start_time = std::clock(); } // postcondition: elapsed()==0
//         timer( const timer& src );      // post: elapsed()==src.elapsed()
//        ~timer(){}
//  timer& operator=( const timer& src );  // post: elapsed()==src.elapsed()
  void   restart() { _start_time = std::clock(); } // post: elapsed()==0
  double elapsed() const                  // return elapsed time in seconds
    { return  double(std::clock() - _start_time) / CLOCKS_PER_SEC; }

  double elapsed_max() const   // return estimated maximum value for elapsed()
  // Portability warning: elapsed_max() may return too high a value on systems
  // where std::clock_t overflows or resets at surprising values.
  {
    return (double((std::numeric_limits<std::clock_t>::max)())
       - double(_start_time)) / double(CLOCKS_PER_SEC); 
  }

  double elapsed_min() const            // return minimum value for elapsed()
   { return double(1)/double(CLOCKS_PER_SEC); }

 private:
  std::clock_t _start_time;
}; // timer

} // namespace boost

#endif  // BOOST_TIMER_HPP

可以看到,在我们构造timer对象的时候,它调用的是 std::clock(),返回程序启动以来的clock数,并且保存在私有变量_start_time中。每次调用elapsed()函数,它会重新调用std::clock()函数获取此时的clock数,然后减去启动clock数,然后除以每秒的clock数来获得已经用了多长时间。

其中CLOCKS_PER_SEC是一个宏定义,#define CLOCKS_PER_SEC ((clock_t)1000)
可以看到它的值是每秒1000.

至于获取最小度量,那就是一次要多少秒,计算很简单,1/CLOCKS_PER_SEC =0.001

其中还有一个函数restart(),调用该函数会重新开始计数,_start_time的值将被重置。

大家看到这里可能会注意到,timer类并没有析构函数,在看下类的定义,只有一个本质为long型的_start_time变量,所以这里其实也没有资源来特意释放的。

既然boost中可以使用timer来获取时间跨度,那么我们在温习以下c++中是怎么使用的。
这里我用了一种不经常使用的方式。

    double time = 0;
    double counts = 0;
    LARGE_INTEGER nFreq;
    LARGE_INTEGER nBeginTime;
    LARGE_INTEGER nEndTime;
    QueryPerformanceFrequency(&nFreq);
    QueryPerformanceCounter(&nBeginTime);//开始计时  
    while (counts++ < 1000000)
    {
        continue;
    }
    QueryPerformanceCounter(&nEndTime);//停止计时  
    time = (double)(nEndTime.QuadPart - nBeginTime.QuadPart) / (double)nFreq.QuadPart;//计算程序执行时间单位为s  
    cout << "运行时间:" << time * 1000 << "ms" << endl;

其中的函数我们先放一边,待会在仔细看,这里我们先看下结果:

运行时间:5.50927ms

百万次级别的count++运算才只用了5毫秒左右,不得不说还是挺快的,当然这和我在代码中写的逻辑比较简单有关。

我们先看下其中用到的LARGE_INTEGER联合体:

typedef union _LARGE_INTEGER {
    struct {
        DWORD LowPart;
        LONG HighPart;
    } DUMMYSTRUCTNAME;
    struct {
        DWORD LowPart;
        LONG HighPart;
    } u;
    LONGLONG QuadPart;
} LARGE_INTEGER;

这个联合体中: LowPart表示低32位,HighPart表示高32位,QuadPart表示一个64位的整型。

如果你的操作系统不支持64位,那么存储数据的时候就应该使用LowPart和HighPart成员来存储,否则的话直接使用QuadPart就好了。

QueryPerformanceFrequency函数:获得机器内部计时器的时钟频率
检索性能计数器的频率。性能计数器的频率在系统启动时固定,并且在所有处理器中保持一致。因此,只需要在应用程序初始化时查询频率,结果就可以被缓存。

原型:

BOOL WINAPI QueryPerformanceFrequency(
  _Out_ LARGE_INTEGER * lpFrequency
);

参数
lpFrequency [out]
指向一个变量的指针,以每秒计数的形式接收当前的性能计数器频率。如果安装的硬件不支持高分辨率性能计数器,则此参数可以为零(在运行Windows XP或更高版本的系统上不会发生此问题)。

返回值
如果安装的硬件支持高分辨率性能计数器,则返回值不为零。

如果函数失败,返回值为零。要获得扩展错误信息,请调用GetLastError。在运行Windows XP或更高版本的系统上,该函数将始终成功,因此永远不会返回零。

QueryPerformanceCounter函数
检索性能计数器的当前值,该值是高分辨率(<1us)时间戳,可用于时间间隔测量。

句法
BOOL WINAPI QueryPerformanceCounter(
Out LARGE_INTEGER * lpPerformanceCount
);

参数
lpPerformanceCount [out]
指向接收当前性能计数器值的变量的指针(以计数为单位)。

返回值
如果函数成功,返回值是非零的。

如果函数失败,返回值为零。要获得扩展错误信息,请调用GetLastError。在运行Windows XP或更高版本的系统上,该函数将始终成功,因此永远不会返回零。

至于怎么计算想必不用多说了吧。。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值