MultiAgentDecisionProcess  Release 0.2.1
Timing.cpp
Go to the documentation of this file.
1 
28 #include "Timing.h"
29 #include <fstream>
30 #include <sys/times.h>
31 #include <limits.h>
32 
33 using namespace std;
34 
35 //Default constructor
37 {
38  _m_timeAtInitialization=GetCpuTime();
39 }
40 
41 //Destructor
43 {
44 }
45 
46 void Timing::Start(const string & id)
47 {
48  Times newTimer;
49  newTimer.start=GetCpuTime();
50  newTimer.end=0;
51  newTimer.hasEnded=false;
52  _m_timesMap[id].push_back(newTimer);
53 }
54 
55 void Timing::Stop(const string & id, clock_t endTime)
56 {
57  map <string, vector<Times> >::iterator it=_m_timesMap.find(id);
58  if(it==_m_timesMap.end())
59  {
60  stringstream ss;
61  ss << "Timing::Stop Could not stop timing event called \""
62  << id << "\", no such event ever started";
63  throw(E(ss.str()));
64  }
65  else
66  {
67  it->second.size();
68  it->second.back().end=endTime;
69  it->second.back().hasEnded=true;
70  }
71 }
72 
73 void Timing::Stop(const string & id)
74 {
75  Stop(id,GetCpuTime());
76 }
77 
78 void Timing::Print() const
79 {
80  map<string, vector<Times> >::const_iterator i;
81  for(i=_m_timesMap.begin(); i!=_m_timesMap.end(); ++i)
82  {
83  const vector<Times> &times=i->second;
84  const string &id=i->first;
85  for(vector<Times>::const_iterator j=times.begin();
86  j!=times.end();++j)
87  {
88  cout << id << ": ";
89  if(j->hasEnded)
90  {
91  cout << j->end - j->start
92  << " start "
93  << j->start << " end "
94  << j->end << endl;
95  }
96  else
97  cout << "still running, started at " << j->start
98  << endl;
99  }
100  }
101 }
102 
104 {
105  map<string, vector<Times> >::const_iterator i;
106  for(i=_m_timesMap.begin(); i!=_m_timesMap.end(); ++i)
107  {
108  const vector<Times> &times=i->second;
109  const string &id=i->first;
110  clock_t total=0,maxTime=0,minTime=INT_MAX,current;
111  int nrSamples=0;
112  for(vector<Times>::const_iterator j=times.begin();
113  j!=times.end();++j)
114  {
115  if(j->hasEnded)
116  {
117  current=j->end - j->start;
118  total+=current;
119  if(current>maxTime)
120  maxTime=current;
121  if(current<minTime)
122  minTime=current;
123 
124  nrSamples++;
125  }
126  }
127 
128  cout << id << ": ";
129  if(nrSamples>0)
130  cout << ClockToSeconds(total)
131  << " s in " << nrSamples << " measurements"
132  << ", max " << ClockToSeconds(maxTime)
133  << ", min " << ClockToSeconds(minTime)
134  << endl;
135  else if((times.size()-nrSamples)>0) // this will only
136  // print the correct
137  // "still running"
138  // time if called from
139  // the same process
140  cout << (times.size()-nrSamples) << " still running, spent "
141  << (ClockToSeconds(GetCpuTime()) -
142  ClockToSeconds(i->second[0].start)) << endl;
143  }
144 }
145 
146 void Timing::Save(const string & filename) const
147 {
148  ofstream fp(filename.c_str());
149  if(!fp)
150  {
151  stringstream ss;
152  ss << "Timing::Save: failed to open file " << filename;
153  throw(E(ss.str()));
154  }
155 
156  Save(fp);
157 }
158 
159 void Timing::Save(ofstream &of) const
160 {
161  of << _m_timeAtInitialization << endl;
162 
163  map<string, vector<Times> >::const_iterator i;
164  for(i=_m_timesMap.begin(); i!=_m_timesMap.end(); ++i)
165  {
166  const vector<Times> &times=i->second;
167  const string &id=i->first;
168 
169  for(vector<Times>::const_iterator j=times.begin();
170  j!=times.end();++j)
171  {
172  if(j->hasEnded)
173  of << id << " " << j->start << " " << j->end << endl;
174  }
175  }
176 }
177 
178 void Timing::Load(const string & filename)
179 {
180  const int bufsize=65536;
181  char buffer[bufsize];
182  bool first=true;
183 
184  ifstream fp(filename.c_str());
185  if(!fp)
186  cerr << "Timing::Load: failed to open file " << filename << endl;
187 
188  _m_timesMap.clear();
189 
190  while(!fp.getline(buffer,bufsize).eof())
191  {
192  {
193  string identification;
194  clock_t start,end;
195  Times times;
196 
197  istringstream is(buffer);
198  if(first)
199  {
200  first=false;
201  is >> start;
202  _m_timeAtInitialization=start;
203  }
204  else
205  {
206  is >> identification;
207  is >> start;
208  is >> end;
209  times.start=start;
210  times.end=end;
211  _m_timesMap[identification].push_back(times);
212  }
213  }
214  }
215 }
216 
217 clock_t Timing::GetCpuTime() const
218 {
219  struct tms timeStruct;
220  times(&timeStruct);
221  return(timeStruct.tms_utime + timeStruct.tms_stime);
222 }
223 
224 //Need this for _SC_CLK_TCK:
225 #include <unistd.h>
226 
227 double Timing::ClockToSeconds(clock_t clockTicks) const
228 {
229  return(static_cast<double>(clockTicks) / sysconf(_SC_CLK_TCK));
230 }
231 
232 void Timing::AddEvent(const string & id, clock_t duration)
233 {
234  Start(id);
235  Stop(id,GetCpuTime()+duration);
236 }
237 
238 vector<double> Timing::GetEventDurations(const string & id)
239 {
240  vector<double> durations;
241 
242  map <string, vector<Times> >::iterator it=_m_timesMap.find(id);
243  if(it==_m_timesMap.end())
244  {
245  stringstream ss;
246  ss << "Timing::GetEventDurations No events called \""
247  << id << "\" have been stored";
248  throw(E(ss.str()));
249  }
250  else
251  {
252  const vector<Times> &times=it->second;
253  for(vector<Times>::const_iterator j=times.begin();
254  j!=times.end();++j)
255  {
256  if(j->hasEnded)
257  durations.push_back(ClockToSeconds(j->end - j->start));
258  }
259  }
260  return(durations);
261 }