TestTimer.h
// TestTimer.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2005
#pragma once
#ifndef Ceda_cxUtils_TestTimer_H
#define Ceda_cxUtils_TestTimer_H
#include "xstring.h"
#include "HPTime.h"
#include <functional>
namespace ceda
{
///////////////////////////////////////////////////////////////////////////////////////////////////
// TestTimer
struct ITestTimerInfo
{
virtual void WriteInfo(xostream& os) = 0;
};
class cxUtils_API TestTimer
{
public:
TestTimer(ITestTimerInfo& info, double timeForTestInSecs, double timeToPrintLine);
bool Next();
int GetCount() const { return m_count; }
double GetElapsedTimeInSeconds() const { return m_timer.GetElapsedTimeInSeconds(); }
private:
ITestTimerInfo& m_info;
double m_timeForTestInSecs;
double m_timeToPrintLine;
int m_count;
int m_numSecs;
HPTimer m_timer;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// RateTimer
class cxUtils_API RateTimer
{
public:
RateTimer(bool bytesPerSec = false, bool traceWhenDestruct = true);
RateTimer(ConstStringZ description, double count, bool bytesPerSec = false, bool traceWhenDestruct = true);
~RateTimer();
// Start timing from now (until it destructs)
void Reset();
void SetDescription(ConstStringZ description);
void AddToCount(double count);
void SetCount(double count) { m_count = count; }
void BeginSkip() { m_timer.BeginSkip(); }
void EndSkip() { m_timer.EndSkip(); }
double GetElapsedTimeInSeconds() const
{
return m_timer.GetElapsedTimeInSeconds();
}
double GetCount() const { return m_count; }
double GetRate() const
{
return m_count / m_timer.GetElapsedTimeInSeconds();
}
void TraceRate(double rate) const;
// Calculate and trace the rate.
void TraceRate() const;
bool UseBytesPerSec() const { return m_bytesPerSec; }
const xstring& Description() const { return m_description; }
private:
xstring m_description;
double m_count;
bool m_bytesPerSec;
bool m_traceWhenDestruct;
HPTimer m_timer;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// MaxRateTimer
enum ERateTimerTrace
{
RT_TRACE_NONE,
RT_TRACE_MAX,
RT_TRACE_AVG,
RT_TRACE_ALL
};
class cxUtils_API MaxRateTimer
{
public:
explicit MaxRateTimer(bool bytesPerSec = false, ERateTimerTrace rtt = RT_TRACE_AVG) :
m_traceWhenDestruct(false),
m_timer(bytesPerSec,false),
m_rtt(rtt),
m_maxRate(0),
m_sumRate(0),
m_num(0)
{
}
MaxRateTimer(ConstStringZ description, double count, bool bytesPerSec = false, ERateTimerTrace rtt = RT_TRACE_AVG) :
m_traceWhenDestruct(true),
m_timer(description,count,bytesPerSec,false),
m_rtt(rtt),
m_maxRate(0),
m_sumRate(0),
m_num(0)
{
}
~MaxRateTimer();
void SetDescription(ConstStringZ description)
{
m_traceWhenDestruct = true;
m_timer.SetDescription(description);
}
double GetElapsedTimeInSeconds() const { return m_timer.GetElapsedTimeInSeconds(); }
void BeginSkip() { m_timer.BeginSkip(); }
void EndSkip() { m_timer.EndSkip(); }
void Begin()
{
m_timer.Reset();
}
void AddToCount(double count) { m_timer.AddToCount(count); }
void SetCount(double count) { m_timer.SetCount(count); }
void End()
{
double r = m_timer.GetRate();
if (m_rtt == RT_TRACE_ALL) m_timer.TraceRate(r);
if (r > m_maxRate) m_maxRate = r;
m_sumRate += r;
++m_num;
}
double GetMaxRate() const { return m_maxRate; }
double GetAvgRate() const { return m_sumRate / m_num; }
double GetCount() const { return m_timer.GetCount(); }
double GetNum() const { return m_num; }
private:
bool m_traceWhenDestruct;
RateTimer m_timer;
ERateTimerTrace m_rtt;
double m_maxRate;
double m_sumRate;
int m_num;
};
inline int CalculateTestCountFromRate(double timeForTestInSecs, double rate, int maxCount = 1000000)
{
int n = maxCount;
while(n/rate > timeForTestInSecs) n /= 10;
if (n==0) n=1;
return n;
}
inline void TimeCode(const char* description, double timeForTestInSecs, double rate, int maxCount, std::function<void(int n)> code)
{
int n = CalculateTestCountFromRate(timeForTestInSecs, rate, maxCount);
ceda::MaxRateTimer t(description,n);
ceda::HPTimer timeTaken;
while(timeTaken.GetElapsedTimeInSeconds() < timeForTestInSecs)
{
t.Begin();
code(n);
t.End();
}
}
} // namespace ceda
#endif // include guard