Skip to content
Snippets Groups Projects
time_tracer.h 3.74 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>

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)
	{		  
	  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);
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() 
	{ 
	  if(debug && pad > 0) 
	    {
	      cout << tmp << "finished" << endl;
	      pad--;
	    }
	  if(timingon)
	    {
	      timingFunction->end();
	    }
	}

      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();
	}

      static void setdebugon() {debug = true;}
      static void settimingon() {timingon = true;}

    protected:
      static bool debug;
      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

      string tmp;
      TimingFunction* timingFunction;

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

}
#endif