前言
时间在写服务端程序中格外的重要常常用于计算延迟,一个常用的计算时间方法就是使用函数调用前后的 clock 之差除以精度算消耗的时机,常用的clock获取方法如下
time() 精度在1s
clock() 常常搭配 CLOCKS_PER_SEC(10^6) 精度在 1us
clock_gettime(CLOCK_MONOTONIC, ...) 精度1ns
gettimeofday() 精度 1us
Timer类
Timer类主要用来计时的一个类。timer变量定义之后即开始计时工作,之后可以调用 elapsed() 方法来测量对象自创建之后所流逝的时间。输出单位s,精度范围在 1us。
Timer使用场景
using boost::timer;
timer t;
Func();
cout << "Func cost:" << t.elapsed() << "s" << endl;
boost Timer实现
class timer
{
public:
timer() { _start_time = std::clock(); }
void 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); }
private:
std::clock_t _start_time;
}; // timer
progress_timer
这个类也是一个类似timer的定时器,只不过它不用我们手动的去调用相应的 elapsed函数,它会在析构的时候自动去输出相应的时间。
progress_timer( std::ostream & os = std::cout );
progress_display
这个类是一个进度条,可以实现程序的时候需要加进度的时候可以考虑这个类。
使用场景
注意一定要使用前置++,后置++没实现相应函数。
vector vec(1000,0);
progress_display pro_display(1000);
for( auto& i : vec) {
operator(i);
++pro_display;
}
实现
progress_display( unsigned long expected_count_, std::ostream & os = std::cout,
const std::string & s1 = "\n", const std::string & s2 = "", const std::string & s3 = "" );
class progress_display : private noncopyable
{
public:
explicit progress_display( unsigned long expected_count_,
std::ostream & os = std::cout,
const std::string & s1 = "\n", //leading strings
const std::string & s2 = "",
const std::string & s3 = "" )
// os is hint; implementation may ignore, particularly in embedded systems
: noncopyable(), m_os(os), m_s1(s1), m_s2(s2), m_s3(s3) { restart(expected_count_); }
void restart( unsigned long expected_count_ )
// Effects: display appropriate scale
// Postconditions: count()==0, expected_count()==expected_count_
{
_count = _next_tic_count = _tic = 0;
_expected_count = expected_count_;
m_os << m_s1 << "0% 10 20 30 40 50 60 70 80 90 100%\n"
<< m_s2 << "|----|----|----|----|----|----|----|----|----|----|"
<< std::endl // endl implies flush, which ensures display
<< m_s3;
if ( !_expected_count ) _expected_count = 1; // prevent divide by zero
} // restart
unsigned long operator+=( unsigned long increment )
// Effects: Display appropriate progress tic if needed.
// Postconditions: count()== original count() + increment
// Returns: count().
{
if ( (_count += increment) >= _next_tic_count ) { display_tic(); }
return _count;
}
unsigned long operator++() { return operator+=( 1 ); }
unsigned long count() const { return _count; }
unsigned long expected_count() const { return _expected_count; }
private:
std::ostream & m_os; // may not be present in all imps
const std::string m_s1; // string is more general, safer than
const std::string m_s2; // const char *, and efficiency or size are
const std::string m_s3; // not issues
unsigned long _count, _expected_count, _next_tic_count;
unsigned int _tic;
void display_tic()
{
// use of floating point ensures that both large and small counts
// work correctly. static_cast<>() is also used several places
// to suppress spurious compiler warnings.
unsigned int tics_needed =
static_cast<unsigned int>(
(static_cast<double>(_count)/_expected_count)*50.0 );
do { m_os << '*' << std::flush; } while ( ++_tic < tics_needed );
_next_tic_count =
static_cast<unsigned long>((_tic/50.0)*_expected_count);
if ( _count == _expected_count ) {
if ( _tic < 51 ) m_os << '*';
m_os << std::endl;
}
} // display_tic
};
posix 其他Timer计时实现
精度us
class Timer{
public:
Timer()
: timeuse_(0)
{}
void clear()
{
timeuse_ = 0;
}
void start()
{
gettimeofday( &start_, NULL );
}
void end()
{
gettimeofday( &end_, NULL );
size_t cost = 1000000 * ( end_.tv_sec - start_.tv_sec ) + end_.tv_usec - start_.tv_usec;
timeuse_ += cost;
}
size_t cost()
{
return timeuse_;
}
float cost_sec()
{
return timeuse_ / 1000000.0;
}
private :
struct timeval start_;
struct timeval end_;
size_t timeuse_;
};