timer.hpp
// 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/header_deprecated.hpp>
BOOST_HEADER_DEPRECATED( "the facilities in <boost/timer/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的计时器使用了标准头文件<ctimer>
里的std::clock()函数,它返回自进程启动以来的clock数,每秒的clock数则由宏CLOCKS_PER_SEC
定义。
time.h
#define CLOCKS_PER_SEC 1000000 /* [XSI] */
而在不同的操作系统中,CLOCKS_PER_SEC
的值不同,比如在win32下,其值是1000,而在linux下为1000000,也就是说在win32中,精度为毫秒,而在linux中,精度为微秒。
timer() { _start_time = std::clock(); }
获取当前的clock数作为计数起点,保存在私有变量_start_time;
restart() { _start_time = std::clock(); }
重新开始计时;
double elapsed() const
{ return double(std::clock() - _start_time) / CLOCKS_PER_SEC; }
获取耗时;
double elapsed_max() const
{
return (double((std::numeric_limits<std::clock_t>::max)())
- double(_start_time)) / double(CLOCKS_PER_SEC);
}
double elapsed_min() const
{ return double(1)/double(CLOCKS_PER_SEC); }
在timer没有定义析构函数, 这样做是正确和安全的。因为它仅有 一个类型为clock_t的成员变量_start_time,故没有必要实现析构函数来特意“释放资源”(也无资源可释放)。
timer接口简单,轻巧好用,适用于大部分的程序计时任务。但使用时,我们必须理解elapsed_min()和elapsed_max()这两个计时精度函数的定义,它们表明了timer的能力。timer不适合高精度的时间测量任务,它的精度依赖于操作系统和编译器,难以做到跨平台。
timer也不适合大跨度时间段的测量,可提供的最大时间跨度只有几百个小时,如果需要天,月等的时间跨度,则应使用date_time库。
#include <iostream>
#include<boost/timer.hpp>
using namespace std;
using namespace boost;
int main() {
timer t;
cout<<"max: "<<t.elapsed_max()<<endl;
cout<<"min: "<<t.elapsed_min()<<endl;
cout<<"time: "<<t.elapsed()<<endl;
t.restart();
cout<<"time: "<<t.elapsed()<<endl;
return 0;
}
progress.hpp
// boost progress.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
// 1 Dec 01 Add leading progress display strings (suggested by Toon Knapen)
// 20 May 01 Introduce several static_casts<> to eliminate warning messages
// (Fixed by Beman, reported by Herve Bronnimann)
// 12 Jan 01 Change to inline implementation to allow use without library
// builds. See docs for more rationale. (Beman Dawes)
// 22 Jul 99 Name changed to .hpp
// 16 Jul 99 Second beta
// 6 Jul 99 Initial boost version
#ifndef BOOST_PROGRESS_HPP
#define BOOST_PROGRESS_HPP
#include <boost/config/header_deprecated.hpp>
BOOST_HEADER_DEPRECATED( "the facilities in <boost/timer/timer.hpp>" )
#include <boost/timer.hpp>
#include <boost/noncopyable.hpp>
#include <boost/cstdint.hpp> // for uintmax_t
#include <iostream> // for ostream, cout, etc
#include <string> // for string
namespace boost {
// progress_timer ----------------------------------------------------------//
// A progress_timer behaves like a timer except that the destructor displays
// an elapsed time message at an appropriate place in an appropriate form.
class progress_timer : public timer, private noncopyable
{
public:
explicit progress_timer( std::ostream & os = std::cout )
// os is hint; implementation may ignore, particularly in embedded systems
: timer(), noncopyable(), m_os(os) {}
~progress_timer()
{
// A) Throwing an exception from a destructor is a Bad Thing.
// B) The progress_timer destructor does output which may throw.
// C) A progress_timer is usually not critical to the application.
// Therefore, wrap the I/O in a try block, catch and ignore all exceptions.
try
{
// use istream instead of ios_base to workaround GNU problem (Greg Chicares)
std::istream::fmtflags old_flags = m_os.setf( std::istream::fixed,
std::istream::floatfield );
std::streamsize old_prec = m_os.precision( 2 );
m_os << elapsed() << " s\n" // "s" is System International d'Unites std
<< std::endl;
m_os.flags( old_flags );
m_os.precision( old_prec );
}
catch (...) {} // eat any exceptions
} // ~progress_timer
private:
std::ostream & m_os;
};
} // namespace boost
#endif // BOOST_PROGRESS_HPP
class progress_timer : public timer, private noncopyable
{}
progress_timer继承了timer的全部能力,可以如timer那样使用;
explicit progress_timer( std::ostream & os = std::cout ): timer(), noncopyable(), m_os(os) {}
注:explicit防止隐示转换
构造函数progress_timer(std::ostream &os),它允许将析构时的输出定向到指定的IO流中,默认为std::cout。如果有特别的需求,可以用其他标准库输出流(ofstream,ostringstream)替换。
~progress_timer()
{
try
{
flags old_flags = m_os.setf( std::istream::fixed, std::istream::floatfield );
std::streamsize old_prec = m_os.precision( 2 );
m_os << elapsed() << " s\n" << std::endl;
m_os.flags( old_flags );
m_os.precision( old_prec );
}
catch (...) {} // eat any exceptions
} // ~progress_timer
将耗时输出到指定的输出流m_os
中;
#include <iostream>
#include <iosfwd>
#include<boost/timer.hpp>
#include<boost/progress.hpp>
#include <sstream>
using namespace std;
using namespace boost;
int main() {
{
progress_timer t2;
}
stringstream ss;
{
progress_timer t1(ss);
}
cout<<ss.str()<<endl;//将输出流ss,显示
cout<<"end...";
return 0;
}
progress_timer对于输出精度只能精确到小数点后两位。