-#include <msp/core/except.h>
-#include <msp/time/units.h>
+#include <msp/core/maputils.h>
#include "profiler.h"
+#include "profilingscope.h"
using namespace std;
return;
period = p;
- for(map<string, ScopeInfo>::iterator i=scopes.begin(); i!=scopes.end(); ++i)
+ for(auto &kvp: scopes)
{
- ScopeInfo &si = i->second;
+ ScopeInfo &si = kvp.second;
if(p==0)
si.history.clear();
else
- si.history.assign(period, Time::zero);
+ si.history.assign(period, CallInfo());
si.hist_pos = 0;
+ si.hist_full = false;
}
}
-void Profiler::add_scope(const std::string &name)
+void Profiler::add_scope(const string &name)
{
if(!scopes.count(name))
{
- map<string, ScopeInfo>::iterator i = scopes.insert(map<string, ScopeInfo>::value_type(name, ScopeInfo())).first;
+ auto i = scopes.insert(make_pair(name, ScopeInfo())).first;
i->second.history.resize(period);
}
}
return old;
}
-void Profiler::record(const string &scope_name, const string &parent, const Time::TimeDelta &time, const Time::TimeDelta &child_t)
+void Profiler::record(const ProfilingScope &scope)
{
- map<string, ScopeInfo>::iterator i = scopes.find(scope_name);
+ auto i = scopes.find(scope.get_name());
if(i==scopes.end())
{
- i = scopes.insert(map<string, ScopeInfo>::value_type(scope_name, ScopeInfo())).first;
+ i = scopes.insert(make_pair(scope.get_name(), ScopeInfo())).first;
+ i->second.first_call = scope.get_entry_time();
i->second.history.resize(period);
}
ScopeInfo &si = i->second;
++si.calls;
- ++si.called_from[parent];
- si.total_time += time;
- si.self_time += time-child_t;
+ if(scope.get_parent())
+ ++si.called_from[scope.get_parent()->get_name()];
+ si.total_time += scope.get_time_spent();
+ si.self_time += scope.get_time_spent()-scope.get_child_time();
if(period)
{
- si.avg_time += time/period-si.history[si.hist_pos]/period;
- si.history[si.hist_pos++] = time;
+ si.avg_time += scope.get_time_spent()/period-si.history[si.hist_pos].duration/period;
+
+ CallInfo &ci = si.history[si.hist_pos];
+ Time::TimeStamp old_entry = ci.entry_time;
+ ci.entry_time = scope.get_entry_time();
+ ci.duration = scope.get_time_spent();
+
+ ++si.hist_pos;
if(si.hist_pos>=period)
si.hist_pos -= period;
+
+ if(si.hist_full)
+ si.calls_per_sec = period*Time::sec/(scope.get_entry_time()-old_entry);
+ else if(si.hist_pos>1)
+ si.calls_per_sec = (si.hist_pos-1)*Time::sec/(scope.get_entry_time()-si.history.front().entry_time);
+
+ if(si.hist_pos==0)
+ si.hist_full = true;
}
else
+ {
si.avg_time = si.total_time/si.calls;
+ if(si.calls>1)
+ si.calls_per_sec = (si.calls-1)*Time::sec/(scope.get_entry_time()-si.first_call);
+ }
}
-const Profiler::ScopeInfo &Profiler::scope(const string &sn) const
+const Profiler::ScopeInfo &Profiler::get_scope(const string &sn) const
{
- map<string, ScopeInfo>::const_iterator i = scopes.find(sn);
- if(i==scopes.end())
- throw KeyError("Unknown scope");
-
- return i->second;
+ return get_item(scopes, sn);
}
Profiler::ScopeInfo::ScopeInfo():
calls(0),
- hist_pos(0)
+ calls_per_sec(0),
+ hist_pos(0),
+ hist_full(false)
{ }
} // namespace Debug