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