Files
MagicSetEditor2/src/script/profiler.cpp
T
twanvl 51dfed69b4 Instead of the new_intrusive<T>() functions, use intrusive(new T)
This means we no longer need 8 different functions for different numbers of arguments, and non-const references can now also be passed to constructors without problems.

git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1443 0fc631ac-6414-0410-93d0-97cfa31319b6
2010-07-21 14:32:28 +00:00

144 lines
4.2 KiB
C++

//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2010 Twan van Laarhoven and Sean Hunt |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <script/profiler.hpp>
#if USE_SCRIPT_PROFILING
// don't use script profiling in final build
#ifndef UNICODE
#error "It looks like you are building the final release; disable USE_SCRIPT_PROFILING!"
#endif
DECLARE_TYPEOF(map<size_t COMMA FunctionProfileP>);
// ----------------------------------------------------------------------------- : Timer
Timer::Timer() {
start = timer_now() + delta;
}
ProfileTime Timer::time() {
ProfileTime end = timer_now() + delta;
ProfileTime diff = end - start;
start = end;
return diff;
}
void Timer::exclude_time() {
ProfileTime delta_delta = time();
delta -= delta_delta;
start -= delta_delta;
}
ProfileTime Timer::delta = 0;
// ----------------------------------------------------------------------------- : FunctionProfile
FunctionProfile profile_root(_("root"));
inline bool compare_time(const FunctionProfileP& a, const FunctionProfileP& b) {
return a->time_ticks < b->time_ticks;
}
void FunctionProfile::get_children(vector<FunctionProfileP>& out) const {
FOR_EACH_CONST(c,children) {
out.push_back(c.second);
}
sort(out.begin(), out.end(), compare_time);
}
FunctionProfile profile_aggr(_("everywhere"));
void profile_aggregate(FunctionProfile& parent, int level, int max_level, const FunctionProfile& p);
void profile_aggregate(FunctionProfile& parent, int level, int max_level, size_t idx, const FunctionProfile& p) {
// add to item at idx
FunctionProfileP& fpp = parent.children[idx];
if (!fpp) {
fpp = intrusive(new FunctionProfile(p.name));
}
fpp->time_ticks += p.time_ticks;
fpp->calls += p.calls;
// recurse
if (level == 0) {
profile_aggregate(parent, level, max_level, p);
}
if (level < max_level) {
profile_aggregate(*fpp, level + 1, max_level, p);
}
}
void profile_aggregate(FunctionProfile& parent, int level, int max_level, const FunctionProfile& p) {
FOR_EACH_CONST(c, p.children) {
profile_aggregate(parent, level, max_level, c.first, *c.second);
}
}
const FunctionProfile& profile_aggregated(int max_level) {
profile_aggr.children.clear();
profile_aggregate(profile_aggr, 0, max_level, profile_root);
return profile_aggr;
}
// ----------------------------------------------------------------------------- : Profiler
FunctionProfile* Profiler::function = &profile_root;
// Enter a function
Profiler::Profiler(Timer& timer, Variable function_name)
: timer(timer)
, parent(function) // push
{
if ((int)function_name >= 0) {
FunctionProfileP& fpp = parent->children[(size_t)function_name << 1 | 1];
if (!fpp) {
fpp = intrusive(new FunctionProfile(variable_to_string(function_name)));
}
function = fpp.get();
}
timer.exclude_time();
}
// Enter a function
Profiler::Profiler(Timer& timer, const Char* function_name)
: timer(timer)
, parent(function) // push
{
FunctionProfileP& fpp = parent->children[(size_t)function_name];
if (!fpp) {
fpp = intrusive(new FunctionProfile(function_name));
}
function = fpp.get();
timer.exclude_time();
}
// Enter a function
Profiler::Profiler(Timer& timer, void* function_object, const String& function_name)
: timer(timer)
, parent(function) // push
{
FunctionProfileP& fpp = parent->children[(size_t)function_object];
if (!fpp) {
fpp = intrusive(new FunctionProfile(function_name));
}
function = fpp.get();
timer.exclude_time();
}
// Leave a function
Profiler::~Profiler() {
ProfileTime time = timer.time();
if (function == parent) return; // don't count
function->time_ticks += time;
function->calls += 1;
function = parent; // pop
}
// ----------------------------------------------------------------------------- : EOF
#endif