]> git.tdb.fi Git - libs/core.git/blob - source/debug/profiler.cpp
Refactor Profiler
[libs/core.git] / source / debug / profiler.cpp
1 #include <msp/core/maputils.h>
2 #include <msp/time/units.h>
3 #include "profiler.h"
4 #include "profilingscope.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace Debug {
10
11 Profiler::Profiler():
12         period(0),
13         inner(0)
14 { }
15
16 void Profiler::set_period(unsigned p)
17 {
18         if(p==period)
19                 return;
20
21         period = p;
22         for(map<string, ScopeInfo>::iterator i=scopes.begin(); i!=scopes.end(); ++i)
23         {
24                 ScopeInfo &si = i->second;
25                 if(p==0)
26                         si.history.clear();
27                 else
28                         si.history.assign(period, Time::zero);
29                 si.hist_pos = 0;
30         }
31 }
32
33 void Profiler::add_scope(const std::string &name)
34 {
35         if(!scopes.count(name))
36         {
37                 map<string, ScopeInfo>::iterator i = scopes.insert(map<string, ScopeInfo>::value_type(name, ScopeInfo())).first;
38                 i->second.history.resize(period);
39         }
40 }
41
42 ProfilingScope *Profiler::enter(ProfilingScope *ps)
43 {
44         ProfilingScope *old = inner;
45         inner = ps;
46         return old;
47 }
48
49 void Profiler::record(const ProfilingScope &scope)
50 {
51         map<string, ScopeInfo>::iterator i = scopes.find(scope.get_name());
52         if(i==scopes.end())
53         {
54                 i = scopes.insert(map<string, ScopeInfo>::value_type(scope.get_name(), ScopeInfo())).first;
55                 i->second.history.resize(period);
56         }
57
58         ScopeInfo &si = i->second;
59         ++si.calls;
60         if(scope.get_parent())
61                 ++si.called_from[scope.get_parent()->get_name()];
62         si.total_time += scope.get_time_spent();
63         si.self_time += scope.get_time_spent()-scope.get_child_time();
64         if(period)
65         {
66                 si.avg_time += scope.get_time_spent()/period-si.history[si.hist_pos]/period;
67                 si.history[si.hist_pos++] = scope.get_time_spent();
68                 if(si.hist_pos>=period)
69                         si.hist_pos -= period;
70         }
71         else
72                 si.avg_time = si.total_time/si.calls;
73 }
74
75 const Profiler::ScopeInfo &Profiler::get_scope(const string &sn) const
76 {
77         return get_item(scopes, sn);
78 }
79
80
81 Profiler::ScopeInfo::ScopeInfo():
82         calls(0),
83         hist_pos(0)
84 { }
85
86 } // namespace Debug
87 } // namespace Msp