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