]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliCodeTimer.cxx
corrected bug in GetValue(UInt_t timeSec) (Haavard)
[u/mrichter/AliRoot.git] / STEER / AliCodeTimer.cxx
CommitLineData
87932dab 1/**************************************************************************
2* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
7* Permission to use, copy, modify and distribute this software and its *
8* documentation strictly for non-commercial purposes is hereby granted *
9* without fee, provided that the above copyright notice appears in all *
10* copies and that both the copyright notice and this permission notice *
11* appear in the supporting documentation. The authors make no claims *
12* about the suitability of this software for any purpose. It is *
13* provided "as is" without express or implied warranty. *
14**************************************************************************/
15
16// $Id$
17
18///
19/// Class to get organized with the way we're timing our methods...
20///
21/// Typical usage is based on macros (like for AliLog related ones AliDebug...)
22///
23/// The idea is to instrument the code with a few macro calls, and then,
24/// at the end of the execution, get a printout of *all* the timers, by using
25/// AliCodeTimer::Instance()->Print()
26/// instead of getting scattered outputs all over the place.
27///
28/// To time a given method, use :
29///
30/// void ClassA::MethodA(....)
31/// {
32/// AliCodeTimerAuto("")
33/// }
34///
35/// To get several timers within a same method, use :
36///
37/// void ClassA::MethodB(...)
38/// {
39/// AliCodeTimerStart("doing something")
40/// ....
41/// AliCodeTimerStop("doing something")
42///
43/// AliCodeTimerStart("doing something else")
44/// ....
45/// AliCodeTimerStop("doing something else")
46/// }
47///
48///
49
50#include "AliCodeTimer.h"
51
52#include <TMap.h>
53#include <TObjString.h>
54#include <TStopwatch.h>
55#include <Riostream.h>
56
57/// \cond CLASSIMP
58ClassImp(AliCodeTimer)
59ClassImp(AliCodeTimer::AliPair)
60/// \endcond
61
62AliCodeTimer* AliCodeTimer::fgInstance(0x0);
63
64//_____________________________________________________________________________
65void
66AliCodeTimer::AliPair::Print(Option_t* opt) const
67{
68 // Print timer information
69 cout << opt << Form("%s R:%.4fs C:%.4fs (%d slices)",
70 Name().Data(),Timer()->RealTime(),
71 Timer()->CpuTime(),Timer()->Counter()-1) << endl;
72}
73
74
75//_____________________________________________________________________________
76AliCodeTimer::AliCodeTimer() : TObject(), fTimers(new TMap)
77{
78 /// Ctor
79 fTimers->SetOwner(kTRUE);
80}
81
82//_____________________________________________________________________________
83AliCodeTimer::~AliCodeTimer()
84{
85 /// Dtor
86 Reset();
87 delete fTimers;
88}
89
90//_____________________________________________________________________________
91AliCodeTimer*
92AliCodeTimer::Instance()
93{
94 // single instance of this class
95 if (!fgInstance) fgInstance = new AliCodeTimer;
96 return fgInstance;
97}
98
99//_____________________________________________________________________________
100void AliCodeTimer::Continue(const char* classname, const char* methodname,
101 const char* message)
102{
103 /// Resume a previously stop timer
104 TStopwatch* t = Stopwatch(classname,methodname,message);
105 if (t)
106 {
107 t->Continue();
108 }
109 else
110 {
111 AliError(Form("No timer for %s/%s/%s",classname,methodname,message));
112 }
113}
114
115//_____________________________________________________________________________
116Double_t AliCodeTimer::CpuTime(const char* classname,
117 const char* methodname,
118 const char* message) const
119{
120 /// Return cpu time for a given timer
121 TStopwatch* t = Stopwatch(classname,methodname,message);
122 if (t)
123 {
124 return t->CpuTime();
125 }
126 else
127 {
128 return 0;
129 }
130}
131
132//_____________________________________________________________________________
133TMap*
134AliCodeTimer::MethodMap(const char* classname) const
135{
136 /// Return the map for a given "classname"
137 return static_cast<TMap*>(fTimers->GetValue(classname));
138}
139
140//_____________________________________________________________________________
141TObjArray*
142AliCodeTimer::MessageArray(const char* classname, const char* methodname) const
143{
144 /// Return the array for a given AliPair (classname,methodname)
145 TMap* m = MethodMap(classname);
146 if ( m )
147 {
148 return static_cast<TObjArray*>(m->GetValue(methodname));
149 }
150 return 0;
151}
152
153//_____________________________________________________________________________
154void AliCodeTimer::PrintMethod(const char* classname, const char* methodname) const
155{
156 /// Print all the timers for a given method
157 TObjArray* messages = MessageArray(classname,methodname);
158 messages->Sort();
159
160 cout << " " << methodname << " ";
161
162 if ( messages->GetLast() == 0 )
163 {
164 AliPair* p = static_cast<AliPair*>(messages->First());
165 p->Print();
166 }
167 else
168 {
169 cout << endl;
170
171 TIter next(messages);
172 AliPair* p;
173
174 while ( ( p = static_cast<AliPair*>(next()) ) )
175 {
176 p->Print(" ");
177 }
178 }
179}
180
181//_____________________________________________________________________________
182void AliCodeTimer::PrintClass(const char* classname) const
183{
184 /// Print all the timers for a given class
185 TMap* methods = MethodMap(classname);
186 TIter next(methods);
187 TObjString* methodname;
188 TObjArray methodNameArray;
189
190 while ( ( methodname = static_cast<TObjString*>(next()) ) )
191 {
192 methodNameArray.Add(methodname);
193 }
194
195 cout << classname << endl;
196
197 methodNameArray.Sort();
198
199 TIter mnext(&methodNameArray);
200
201 while ( ( methodname = static_cast<TObjString*>(mnext()) ) )
202 {
203 PrintMethod(classname,methodname->String().Data());
204 }
205}
206
207//_____________________________________________________________________________
208void AliCodeTimer::Print(Option_t* /*opt*/) const
209{
210 /// Print all the timers we hold
211 TIter next(fTimers);
212 TObjString* classname;
213 TObjArray classNameArray;
214
215 while ( ( classname = static_cast<TObjString*>(next()) ) )
216 {
217 classNameArray.Add(classname);
218 }
219
220 classNameArray.Sort();
221
222 TIter cnext(&classNameArray);
223 while ( ( classname = static_cast<TObjString*>(cnext()) ) )
224 {
225 PrintClass(classname->String().Data());
226 }
227}
228
229//_____________________________________________________________________________
230Double_t
231AliCodeTimer::RealTime(const char* classname, const char* methodname,
232 const char* message) const
233{
234 /// Return real time of a given time
235 TStopwatch* t = Stopwatch(classname,methodname,message);
236 if (t)
237 {
238 return t->RealTime();
239 }
240 else
241 {
242 return 0;
243 }
244}
245
246//_____________________________________________________________________________
247void
248AliCodeTimer::Reset()
249{
250 /// Reset
251 TIter next(fTimers);
252 TObjString* classname;
253
254 while ( ( classname = static_cast<TObjString*>(next()) ) )
255 {
256 TMap* m = static_cast<TMap*>(fTimers->GetValue(classname->String().Data()));
257 m->DeleteAll();
258 }
259
260 fTimers->DeleteAll();
261}
262
263//_____________________________________________________________________________
264void
265AliCodeTimer::Start(const char* classname, const char* methodname,
266 const char* message)
267{
268 /// Start a given time
269 TStopwatch* t = Stopwatch(classname,methodname,message);
270 if (!t)
271 {
272 TMap* m = MethodMap(classname);
273 if (!m)
274 {
275 m = new TMap;
276 m->SetOwner(kTRUE);
277 fTimers->Add(new TObjString(classname),m);
278 }
279 TObjArray* messages = MessageArray(classname,methodname);
280 if (!messages)
281 {
282 messages = new TObjArray;
283 messages->SetOwner(kTRUE);
284 m->Add(new TObjString(methodname),messages);
285 }
286 t = new TStopwatch;
287 t->Start(kTRUE);
288 t->Stop();
289 messages->Add(new AliPair(new TObjString(message),t));
290 }
291 t->Start(kFALSE);
292}
293
294//_____________________________________________________________________________
295void
296AliCodeTimer::Stop(const char* classname, const char* methodname,
297 const char* message)
298{
299 /// Stop a given timer
300 TStopwatch* t = Stopwatch(classname,methodname,message);
301 if (!t)
302 {
303 AliError(Form("No timer for %s/%s/%s",classname,methodname,message));
304 }
305 else
306 {
307 t->Stop();
308 }
309}
310
311//_____________________________________________________________________________
312TStopwatch*
313AliCodeTimer::Stopwatch(const char* classname, const char* methodname,
314 const char* message) const
315{
316 /// Return the internal TStopwatch for a given timer
317 TObjArray* a = MessageArray(classname,methodname);
318 if ( a )
319 {
320 if (message)
321 {
322 TIter next(a);
323 AliPair* p;
324 while ( ( p = static_cast<AliPair*>(next()) ) )
325 {
326 TString s = p->Name();
327 if ( s == TString(message) )
328 {
329 return p->Timer();
330 }
331 }
332 }
333 else
334 {
335 return static_cast<TStopwatch*>(a->First());
336 }
337 }
338 return 0x0;
339}