Skip to content
Snippets Groups Projects
time_tracer.h 4.37 KiB
Newer Older
Mark Woolrich's avatar
Mark Woolrich committed
/*  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>
Mark Woolrich's avatar
Mark Woolrich committed
#include <stack>
Mark Woolrich's avatar
Mark Woolrich committed

namespace Utilities{

  class TimingFunction
    {
    public:
      TimingFunction(const char * pstr):
	str(pstr),
Mark Woolrich's avatar
Mark Woolrich committed
	time_taken(0),
Mark Woolrich's avatar
Mark Woolrich committed
	times_called(0)
	{}

Mark Woolrich's avatar
Mark Woolrich committed
      class comparer_name
Mark Woolrich's avatar
Mark Woolrich committed
	{
	public:
	  bool operator()(const TimingFunction* t1, const TimingFunction* t2) const
	    {
	      return strcmp(t1->str, t2->str) < 0;
	    }
	};

Mark Woolrich's avatar
Mark Woolrich committed
      class comparer_time_taken
	{
	public:
	  bool operator()(const TimingFunction* t1, const TimingFunction* t2) const
	    {
	      return t1->time_taken > t2->time_taken;
	    }
	};

Mark Woolrich's avatar
Mark Woolrich committed
      void start() {start_time = clock();}
      void end() {time_taken += clock()-start_time; times_called++;}

Mark Woolrich's avatar
Mark Woolrich committed
      friend comparer_name;
      friend comparer_time_taken;
Mark Woolrich's avatar
Mark Woolrich committed
      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);
Mark Woolrich's avatar
Mark Woolrich committed
      ostr << "<td align=center>" << float(t->time_taken)/CLOCKS_PER_SEC;
Mark Woolrich's avatar
Mark Woolrich committed
      ostr.setf(ios::scientific, ios::floatfield);
Mark Woolrich's avatar
Mark Woolrich committed
      ostr <<  "<td align=center>" << t->times_called <<  "<td align=center>" << (t->time_taken/float(t->times_called))/CLOCKS_PER_SEC;
Mark Woolrich's avatar
Mark Woolrich committed
      ostr << "</tr>";
      return ostr;
    }

  // Non Newmat Tracer:
  class Time_Tracer
    {
    public:
      Time_Tracer(char* str)
	{		  
Mark Woolrich's avatar
Mark Woolrich committed
	  if(instantstack || runningstack)
Mark Woolrich's avatar
Mark Woolrich committed
	    {
	      tmp = "";
	      pad++;
	      for(unsigned int i = 0; i < pad; i++)
		tmp = tmp + "  ";
	      
Mark Woolrich's avatar
Mark Woolrich committed
	      stk.push(string(str));

	      if(runningstack)
		cout << tmp << str << endl;
Mark Woolrich's avatar
Mark Woolrich committed
	    }
	  if(timingon)
	    {
	      // see if already in list:
	      timingFunction = new TimingFunction(str);
Mark Woolrich's avatar
Mark Woolrich committed
	      set<TimingFunction*, TimingFunction::comparer_name>::iterator it = timingFunctions.find(timingFunction);
Mark Woolrich's avatar
Mark Woolrich committed
	      if(it== timingFunctions.end())
		{		  
		  timingFunctions.insert(timingFunction);
		}
	      else
		{
Mark Woolrich's avatar
Mark Woolrich committed
		  delete timingFunction;
Mark Woolrich's avatar
Mark Woolrich committed
		  timingFunction = *it;
		}
		
	      timingFunction->start();
	    }
	}
	
      virtual ~Time_Tracer() 
	{ 
Mark Woolrich's avatar
Mark Woolrich committed
	  if(instantstack)
	    stk.pop();

	  if(runningstack && pad > 0) 
Mark Woolrich's avatar
Mark Woolrich committed
	    {
	      cout << tmp << "finished" << endl;
	      pad--;
	    }
	  if(timingon)
	    {
	      timingFunction->end();
	    }
Mark Woolrich's avatar
Mark Woolrich committed
	}

      static void dump_times(const string& dir)
	{
Mark Woolrich's avatar
Mark Woolrich committed
	  multiset<TimingFunction*, TimingFunction::comparer_time_taken> timingFunctionsByTimeTaken(timingFunctions.begin(), timingFunctions.end());
	  
Mark Woolrich's avatar
Mark Woolrich committed
	  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;	  
Mark Woolrich's avatar
Mark Woolrich committed
	  copy(timingFunctionsByTimeTaken.begin(), timingFunctionsByTimeTaken.end(), ostream_iterator<TimingFunction*>(out, "\n"));	
Mark Woolrich's avatar
Mark Woolrich committed
	  out << "</table></BODY></HTML>" << endl;
	  out.close();
	}

Mark Woolrich's avatar
Mark Woolrich committed
      static void dump_instant_stack()
	{
	  // tmp stack to put values into for restoring stack after outputting
	  stack<string> tmpstk;

	  while(!stk.empty())
	    {
	  
	      cout << stk.top() << endl;
	      tmpstk.push(stk.top());
	      stk.pop();
	    }

	  while(!tmpstk.empty())
	    {
	      stk.push(tmpstk.top());
	      tmpstk.pop();
	    }
	}

      static void setinstantstackon() {instantstack = true;}
      static void setrunningstackon() {runningstack = true;}
Mark Woolrich's avatar
Mark Woolrich committed
      static void settimingon() {timingon = true;}

    protected:
Mark Woolrich's avatar
Mark Woolrich committed
      static bool instantstack;
      static bool runningstack;
Mark Woolrich's avatar
Mark Woolrich committed
      static bool timingon;
      static unsigned int pad;
Mark Woolrich's avatar
Mark Woolrich committed
      static set<TimingFunction*, TimingFunction::comparer_name> timingFunctions;
Mark Woolrich's avatar
Mark Woolrich committed
      static stack<string> stk;
Mark Woolrich's avatar
Mark Woolrich committed

      string tmp;
      TimingFunction* timingFunction;

    private:
      Time_Tracer();
      const Time_Tracer& operator=(Time_Tracer&);
      Time_Tracer(Time_Tracer&);
    };

}
#endif