-
Mark Woolrich authoredMark Woolrich authored
time_tracer.h 3.71 KiB
/* Time_Tracer.h
Mark Woolrich, FMRIB Image Analysis Group
Copyright (C) 1999-2000 University of Oxford */
/* CCOPYRIGHT */
#if !defined(Time_Tracer_h)
#define Time_Tracer_h
#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include <set>
namespace Utilities{
class TimingFunction
{
public:
TimingFunction(const char * pstr):
str(pstr),
time_taken(0),
times_called(0)
{}
class comparer_name
{
public:
bool operator()(const TimingFunction* t1, const TimingFunction* t2) const
{
return strcmp(t1->str, t2->str) < 0;
}
};
class comparer_time_taken
{
public:
bool operator()(const TimingFunction* t1, const TimingFunction* t2) const
{
return t1->time_taken > t2->time_taken;
}
};
void start() {start_time = clock();}
void end() {time_taken += clock()-start_time; times_called++;}
friend comparer_name;
friend comparer_time_taken;
friend ostream& operator<<(ostream& ostr, const TimingFunction* t);
protected:
const char* str;
clock_t time_taken;
int times_called;
clock_t start_time;
private:
TimingFunction();
const TimingFunction& operator=(TimingFunction&);
TimingFunction(TimingFunction&);
};
inline ostream& operator<<(ostream& ostr, const TimingFunction* t)
{
ostr << "<tr><td>" << t->str;
ostr.setf(0, ios::floatfield);
ostr << "<td align=center>" << float(t->time_taken)/CLOCKS_PER_SEC;
ostr.setf(ios::scientific, ios::floatfield);
ostr << "<td align=center>" << t->times_called << "<td align=center>" << (t->time_taken/float(t->times_called))/CLOCKS_PER_SEC;
ostr << "</tr>";
return ostr;
}
// Non Newmat Tracer:
class Time_Tracer
{
public:
Time_Tracer(char* str)
{
if(debug)
{
tmp = "";
pad++;
for(unsigned int i = 0; i < pad; i++)
tmp = tmp + " ";
cout << tmp << str << endl;
}
if(timingon)
{
// see if already in list:
timingFunction = new TimingFunction(str);
set<TimingFunction*, TimingFunction::comparer_name>::iterator it = timingFunctions.find(timingFunction);
if(it== timingFunctions.end())
{
timingFunctions.insert(timingFunction);
}
else
{
timingFunction = *it;
}
timingFunction->start();
}
}
virtual ~Time_Tracer()
{
if(debug && pad > 0)
{
cout << tmp << "finished" << endl;
pad--;
}
if(timingon)
{
timingFunction->end();
}
}
static void dump_times(const string& dir)
{
multiset<TimingFunction*, TimingFunction::comparer_time_taken> timingFunctionsByTimeTaken(timingFunctions.begin(), timingFunctions.end());
ofstream out;
out.open((dir + "/timings.html").c_str(), ios::out);
out << "<HTML><TITLE>Tracer Timings</TITLE><BODY><table border=3 cellspacing=5>" << endl;
out << "<tr><td>Function<td align=center>Total Time(secs)<td align=center>Num of calls<td align=center>Time per call(secs)</tr>" << endl;
copy(timingFunctionsByTimeTaken.begin(), timingFunctionsByTimeTaken.end(), ostream_iterator<TimingFunction*>(out, "\n"));
out << "</table></BODY></HTML>" << endl;
out.close();
}
static void setdebugon() {debug = true;}
static void settimingon() {timingon = true;}
protected:
static bool debug;
static bool timingon;
static unsigned int pad;
static set<TimingFunction*, TimingFunction::comparer_name> timingFunctions;
string tmp;
TimingFunction* timingFunction;
private:
Time_Tracer();
const Time_Tracer& operator=(Time_Tracer&);
Time_Tracer(Time_Tracer&);
};
}
#endif