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或更高版本的系统上,该函数将始终成功,因此永远不会返回零。
至于怎么计算想必不用多说了吧。。