[ROOT] Tstopwatch Constructor / Start() behaviour

From: ANCIANT E. (eric.anciant@sodern.fr)
Date: Wed Sep 22 2004 - 15:00:59 MEST


Hello rooters,

I've been fooled several times by the TStopwatch behaviour, for example
doing the following :

 TStopwatch watch; // ... Constructor ...

< ... Lots of stuff ... >

 watch.Start(); // or watch.Start(kTRUE) which is the same

< things whose timing I would like to measure >

 watch.Stop(); // optional in fact ...
 cout << watch.CpuTime() << endl;

The timing I got is not the timing between the call to Start() and the
call to Stop()
(which I tend to expect ) but between the constructor and the call to
Stop() !

The reason is that the constructor Starts the stopwath (therefore in a
'kRunning' state),
Then the Start(kTRUE), though reseting the total CPU and Real times,
does not reset
The Start times, which are left to there values that got set at
construction time.

Practicaly, to have things working (the way I expect it) is to have to
Stop() any stopwatch once (typically just after constructing it) before
using it (especially 'global' or class-member stopwatches )

So I wonder :
- Starting the stopwatch at creation sounds harmless,
- Protecting the start time against several call to Start(kFALSE)
through the kRunning mechanism is fine (...)
- However I really wonder what is point, when Start( bool reset = kTRUE
) is invoqued, to reset the 'total' times and NOT the 'start' ones ? i.e
shouldn't the Start() implementation be ? :

void TStopwatch::Start(Bool_t reset)
{
   // Start the stopwatch. If reset is kTRUE reset the stopwatch before
   // starting it (including the stopwatch counter).
   // Use kFALSE to continue timing after a Stop() without
   // resetting the stopwatch.

   if (reset) {
      fTotalCpuTime  = 0;
      fTotalRealTime = 0;
      fCounter       = 0;
      fStartRealTime = GetRealTime();
      fStartCpuTime  = GetCPUTime();
   }
   if (fState != kRunning) {
      fStartRealTime = GetRealTime();
      fStartCpuTime  = GetCPUTime();
   }
   fState = kRunning;
   fCounter++;
}

I know it is not easy to change a default behaviour of a class, but I
also bet in a few months from now I'll get fooled
 again (Am I the only one ?) Am I missing somethings ?

eric



/************* QUOTE FROM Tstopwath.cxx
***********************************************************/
//______________________________________________________________________
________
 TStopwatch::TStopwatch()
{
   // Create a stopwatch and start it.

#ifdef R__UNIX
   if (!gTicks) gTicks = (Double_t)sysconf(_SC_CLK_TCK);
#endif
   fState         = kUndefined;
   fTotalCpuTime  = 0;
   fTotalRealTime = 0;
   fCounter       = 0;
   Start();
}

//______________________________________________________________________
________
 void TStopwatch::Start(Bool_t reset)
{
   // Start the stopwatch. If reset is kTRUE reset the stopwatch before
   // starting it (including the stopwatch counter).
   // Use kFALSE to continue timing after a Stop() without
   // resetting the stopwatch.

   if (reset) {
      fTotalCpuTime  = 0;
      fTotalRealTime = 0;
      fCounter       = 0;
   }
   if (fState != kRunning) {  // !!! <<============  because the watch
is running, start times are not reset
      fStartRealTime = GetRealTime();
      fStartCpuTime  = GetCPUTime();
   }
   fState = kRunning;
   fCounter++;
}


//______________________________________________________________________
________
 void TStopwatch::Stop()
{
   // Stop the stopwatch.

   fStopRealTime = GetRealTime();
   fStopCpuTime  = GetCPUTime();

   if (fState == kRunning) {
      fTotalCpuTime  += fStopCpuTime  - fStartCpuTime;
      fTotalRealTime += fStopRealTime - fStartRealTime;
   }
   fState = kStopped;
}

//______________________________________________________________________
________
 Double_t TStopwatch::CpuTime()
{
   // Return the cputime passed between the start and stop events. If
the
   // stopwatch was still running stop it first.

   if (fState == kUndefined)
      Error("CpuTime", "stopwatch not started");

   if (fState == kRunning)
      Stop();

   return fTotalCpuTime;
}

***********
Ce message et eventuellement les pieces jointes sont exclusivement transmis a l'usage de leur destinataire. Leur contenu est confidentiel. Si vous n etes pas le bon destinataire nous vous demandons de ne pas conserver, copier, utiliser ou divulguer cette communication. Merci de le detruire et de me notifier cette erreur.

INTERNET ne permettant pas d assurer l integrite de ce message, SODERN decline toute responsabilite au cas ou il aurait ete intercepte ou modifie.


This message and possibly any attachments are transmitted for the exclusive use of their addressee. Their content is confidential. If you are not the intended recipient please do not keep, copy, use or disclose this communication to others. Also Please delete it and notify the sender at once.

Because of the nature of INTERNET the sender is not in a position to ensure the integrity of this message, therefore SODERN disclaims any liability whatsoever in the event of this message having been intercepted and/or altered.



This archive was generated by hypermail 2b29 : Sun Jan 02 2005 - 05:50:09 MET