X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fdebug%2Fprofiler.cpp;h=c4c880b70241c826d87e7db7ba3598bc8034be84;hp=af1380000639c9698ae333046654b11026929495;hb=20c897ece781e18ba54c41fd68e232ce566a938d;hpb=cac699732d60d05edc73c39075b85f45a91a620a diff --git a/source/debug/profiler.cpp b/source/debug/profiler.cpp index af13800..c4c880b 100644 --- a/source/debug/profiler.cpp +++ b/source/debug/profiler.cpp @@ -1,13 +1,6 @@ -/* $Id$ - -This file is part of libmspcore -Copyright © 2007 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - -#include "../core/except.h" -#include "../time/units.h" +#include #include "profiler.h" +#include "profilingscope.h" using namespace std; @@ -24,72 +17,91 @@ void Profiler::set_period(unsigned p) if(p==period) return; - period=p; + period = p; for(map::iterator i=scopes.begin(); i!=scopes.end(); ++i) { - ScopeInfo &si=i->second; + ScopeInfo &si = i->second; if(p==0) si.history.clear(); else - si.history.assign(period, Time::zero); - si.hist_pos=0; + 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::iterator i=scopes.insert(map::value_type(name, ScopeInfo())).first; + map::iterator i = scopes.insert(map::value_type(name, ScopeInfo())).first; i->second.history.resize(period); } } ProfilingScope *Profiler::enter(ProfilingScope *ps) { - ProfilingScope *old=inner; - inner=ps; + ProfilingScope *old = inner; + inner = ps; 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::iterator i=scopes.find(scope_name); + map::iterator i = scopes.find(scope.get_name()); if(i==scopes.end()) { - i=scopes.insert(map::value_type(scope_name, ScopeInfo())).first; + i = scopes.insert(map::value_type(scope.get_name(), ScopeInfo())).first; + i->second.first_call = scope.get_entry_time(); i->second.history.resize(period); } - ScopeInfo &si=i->second; + 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; + 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; + { + 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::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