Line data Source code
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 : // $Id$
16 :
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 : // }
46 :
47 : #include "AliCodeTimer.h"
48 :
49 : #include <TMap.h>
50 : #include <TObjString.h>
51 : #include <TStopwatch.h>
52 : #include <Riostream.h>
53 :
54 : using std::endl;
55 : using std::cout;
56 : /// \cond CLASSIMP
57 176 : ClassImp(AliCodeTimer)
58 176 : ClassImp(AliCodeTimer::AliPair)
59 : /// \endcond
60 :
61 : AliCodeTimer* AliCodeTimer::fgInstance(0x0);
62 :
63 : //_____________________________________________________________________________
64 : void
65 : AliCodeTimer::AliPair::Print(Option_t* opt) const
66 : {
67 : // Print timer information
68 2245 : cout << opt << Form("%s R:%.4fs C:%.4fs (%d slices)",
69 898 : Name().Data(),Timer()->RealTime(),
70 1347 : Timer()->CpuTime(),Timer()->Counter()-1) << endl;
71 449 : }
72 :
73 :
74 : //_____________________________________________________________________________
75 20 : AliCodeTimer::AliCodeTimer() : TObject(), fTimers(new TMap)
76 25 : {
77 : /// Ctor
78 5 : fTimers->SetOwner(kTRUE);
79 10 : }
80 :
81 : //_____________________________________________________________________________
82 : AliCodeTimer::~AliCodeTimer()
83 0 : {
84 : /// Dtor
85 0 : Reset();
86 0 : delete fTimers;
87 0 : }
88 :
89 : //_____________________________________________________________________________
90 : AliCodeTimer*
91 : AliCodeTimer::Instance()
92 : {
93 : // single instance of this class
94 1072552 : if (!fgInstance) fgInstance = new AliCodeTimer;
95 536271 : return fgInstance;
96 0 : }
97 :
98 : //_____________________________________________________________________________
99 : void AliCodeTimer::Continue(const char* classname, const char* methodname,
100 : const char* message)
101 : {
102 : /// Resume a previously stop timer
103 0 : TStopwatch* t = Stopwatch(classname,methodname,message);
104 0 : if (t)
105 : {
106 0 : t->Continue();
107 0 : }
108 : else
109 : {
110 0 : AliError(Form("No timer for %s/%s/%s",classname,methodname,message));
111 : }
112 0 : }
113 :
114 : //_____________________________________________________________________________
115 : Double_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 0 : TStopwatch* t = Stopwatch(classname,methodname,message);
121 0 : if (t)
122 : {
123 0 : return t->CpuTime();
124 : }
125 : else
126 : {
127 0 : return 0;
128 : }
129 0 : }
130 :
131 : //_____________________________________________________________________________
132 : TMap*
133 : AliCodeTimer::MethodMap(const char* classname) const
134 : {
135 : /// Return the map for a given "classname"
136 1074448 : return static_cast<TMap*>(fTimers->GetValue(classname));
137 : }
138 :
139 : //_____________________________________________________________________________
140 : TObjArray*
141 : AliCodeTimer::MessageArray(const char* classname, const char* methodname) const
142 : {
143 : /// Return the array for a given AliPair (classname,methodname)
144 1073708 : TMap* m = MethodMap(classname);
145 536854 : if ( m )
146 : {
147 536801 : return static_cast<TObjArray*>(m->GetValue(methodname));
148 : }
149 53 : return 0;
150 536854 : }
151 :
152 : //_____________________________________________________________________________
153 : void AliCodeTimer::PrintMethod(const char* classname, const char* methodname) const
154 : {
155 : /// Print all the timers for a given method
156 614 : TObjArray* messages = MessageArray(classname,methodname);
157 307 : messages->Sort();
158 :
159 307 : cout << " " << methodname << " ";
160 :
161 307 : if ( messages->GetLast() == 0 )
162 : {
163 282 : AliPair* p = static_cast<AliPair*>(messages->First());
164 282 : p->Print();
165 282 : }
166 : else
167 : {
168 25 : cout << endl;
169 :
170 25 : TIter next(messages);
171 : AliPair* p;
172 :
173 409 : while ( ( p = static_cast<AliPair*>(next()) ) )
174 : {
175 167 : p->Print(" ");
176 : }
177 25 : }
178 307 : }
179 :
180 : //_____________________________________________________________________________
181 : void AliCodeTimer::PrintClass(const char* classname) const
182 : {
183 : /// Print all the timers for a given class
184 178 : TMap* methods = MethodMap(classname);
185 89 : TIter next(methods);
186 : TObjString* methodname;
187 89 : TObjArray methodNameArray;
188 :
189 792 : while ( ( methodname = static_cast<TObjString*>(next()) ) )
190 : {
191 307 : methodNameArray.Add(methodname);
192 : }
193 :
194 178 : cout << classname << endl;
195 :
196 89 : methodNameArray.Sort();
197 :
198 89 : TIter mnext(&methodNameArray);
199 :
200 792 : while ( ( methodname = static_cast<TObjString*>(mnext()) ) )
201 : {
202 614 : PrintMethod(classname,methodname->String().Data());
203 : }
204 89 : }
205 :
206 : //_____________________________________________________________________________
207 : void AliCodeTimer::Print(Option_t* /*opt*/) const
208 : {
209 : /// Print all the timers we hold
210 10 : TIter next(fTimers);
211 : TObjString* classname;
212 5 : TObjArray classNameArray;
213 :
214 188 : while ( ( classname = static_cast<TObjString*>(next()) ) )
215 : {
216 89 : classNameArray.Add(classname);
217 : }
218 :
219 5 : classNameArray.Sort();
220 :
221 5 : TIter cnext(&classNameArray);
222 188 : while ( ( classname = static_cast<TObjString*>(cnext()) ) )
223 : {
224 178 : PrintClass(classname->String().Data());
225 : }
226 5 : }
227 :
228 : //_____________________________________________________________________________
229 : Double_t
230 : AliCodeTimer::RealTime(const char* classname, const char* methodname,
231 : const char* message) const
232 : {
233 : /// Return real time of a given time
234 0 : TStopwatch* t = Stopwatch(classname,methodname,message);
235 0 : if (t)
236 : {
237 0 : return t->RealTime();
238 : }
239 : else
240 : {
241 0 : return 0;
242 : }
243 0 : }
244 :
245 : //_____________________________________________________________________________
246 : void
247 : AliCodeTimer::Reset()
248 : {
249 : /// Reset
250 0 : TIter next(fTimers);
251 : TObjString* classname;
252 :
253 0 : while ( ( classname = static_cast<TObjString*>(next()) ) )
254 : {
255 0 : TMap* m = static_cast<TMap*>(fTimers->GetValue(classname->String().Data()));
256 0 : m->DeleteAll();
257 : }
258 :
259 0 : fTimers->DeleteAll();
260 0 : }
261 :
262 : //_____________________________________________________________________________
263 : void
264 : AliCodeTimer::Start(const char* classname, const char* methodname,
265 : const char* message)
266 : {
267 : /// Start a given time
268 536266 : TStopwatch* t = Stopwatch(classname,methodname,message);
269 268133 : if (!t)
270 : {
271 281 : TMap* m = MethodMap(classname);
272 281 : if (!m)
273 : {
274 53 : m = new TMap;
275 53 : m->SetOwner(kTRUE);
276 106 : fTimers->Add(new TObjString(classname),m);
277 53 : }
278 281 : TObjArray* messages = MessageArray(classname,methodname);
279 281 : if (!messages)
280 : {
281 199 : messages = new TObjArray;
282 199 : messages->SetOwner(kTRUE);
283 398 : m->Add(new TObjString(methodname),messages);
284 199 : }
285 281 : t = new TStopwatch;
286 281 : t->Start(kTRUE);
287 281 : t->Stop();
288 1124 : messages->Add(new AliPair(new TObjString(message),t));
289 281 : }
290 268133 : t->Start(kFALSE);
291 268133 : }
292 :
293 : //_____________________________________________________________________________
294 : void
295 : AliCodeTimer::Stop(const char* classname, const char* methodname,
296 : const char* message)
297 : {
298 : /// Stop a given timer
299 536266 : TStopwatch* t = Stopwatch(classname,methodname,message);
300 268133 : if (!t)
301 : {
302 0 : AliError(Form("No timer for %s/%s/%s",classname,methodname,message));
303 0 : }
304 : else
305 : {
306 268133 : t->Stop();
307 : }
308 268133 : }
309 :
310 : //_____________________________________________________________________________
311 : TStopwatch*
312 : AliCodeTimer::Stopwatch(const char* classname, const char* methodname,
313 : const char* message) const
314 : {
315 : /// Return the internal TStopwatch for a given timer
316 1072532 : TObjArray* a = MessageArray(classname,methodname);
317 536266 : if ( a )
318 : {
319 536067 : if (message)
320 : {
321 536067 : TIter next(a);
322 : AliPair* p;
323 1929957 : while ( ( p = static_cast<AliPair*>(next()) ) )
324 : {
325 696863 : TString s = p->Name();
326 2090589 : if ( s == TString(message) )
327 : {
328 535985 : return p->Timer();
329 : }
330 857741 : }
331 536149 : }
332 : else
333 : {
334 0 : return static_cast<TStopwatch*>(a->First());
335 : }
336 : }
337 281 : return 0x0;
338 536266 : }
|