annotate base/Profiler.cpp @ 83:76d4fbab5f20

replace the QDial by sliders
author lbajardsilogic
date Fri, 22 Jun 2007 12:49:50 +0000
parents fc9323a41f5a
children be6f263fa0ab
rev   line source
lbajardsilogic@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
lbajardsilogic@0 2
lbajardsilogic@0 3 /*
lbajardsilogic@0 4 Sonic Visualiser
lbajardsilogic@0 5 An audio file viewer and annotation editor.
lbajardsilogic@0 6 Centre for Digital Music, Queen Mary, University of London.
lbajardsilogic@0 7
lbajardsilogic@0 8 This program is free software; you can redistribute it and/or
lbajardsilogic@0 9 modify it under the terms of the GNU General Public License as
lbajardsilogic@0 10 published by the Free Software Foundation; either version 2 of the
lbajardsilogic@0 11 License, or (at your option) any later version. See the file
lbajardsilogic@0 12 COPYING included with this distribution for more information.
lbajardsilogic@0 13 */
lbajardsilogic@0 14
lbajardsilogic@0 15 /*
lbajardsilogic@0 16 This is a modified version of a source file from the
lbajardsilogic@0 17 Rosegarden MIDI and audio sequencer and notation editor.
lbajardsilogic@0 18 This file copyright 2000-2006 Chris Cannam, Guillaume Laurent,
lbajardsilogic@0 19 and QMUL.
lbajardsilogic@0 20 */
lbajardsilogic@0 21
lbajardsilogic@0 22 #include <iostream>
lbajardsilogic@0 23 #include "Profiler.h"
lbajardsilogic@0 24
lbajardsilogic@0 25 #include <vector>
lbajardsilogic@0 26 #include <algorithm>
lbajardsilogic@0 27 #include <set>
lbajardsilogic@0 28 #include <map>
lbajardsilogic@0 29
lbajardsilogic@0 30 using std::cerr;
lbajardsilogic@0 31 using std::endl;
lbajardsilogic@0 32
lbajardsilogic@0 33 Profiles* Profiles::m_instance = 0;
lbajardsilogic@0 34
lbajardsilogic@0 35 Profiles* Profiles::getInstance()
lbajardsilogic@0 36 {
lbajardsilogic@0 37 if (!m_instance) m_instance = new Profiles();
lbajardsilogic@0 38
lbajardsilogic@0 39 return m_instance;
lbajardsilogic@0 40 }
lbajardsilogic@0 41
lbajardsilogic@0 42 Profiles::Profiles()
lbajardsilogic@0 43 {
lbajardsilogic@0 44 }
lbajardsilogic@0 45
lbajardsilogic@0 46 Profiles::~Profiles()
lbajardsilogic@0 47 {
lbajardsilogic@0 48 dump();
lbajardsilogic@0 49 }
lbajardsilogic@0 50
lbajardsilogic@0 51 void Profiles::accumulate(
lbajardsilogic@0 52 #ifndef NO_TIMING
lbajardsilogic@0 53 const char* id, clock_t time, RealTime rt
lbajardsilogic@0 54 #else
lbajardsilogic@0 55 const char*, clock_t, RealTime
lbajardsilogic@0 56 #endif
lbajardsilogic@0 57 )
lbajardsilogic@0 58 {
lbajardsilogic@0 59 #ifndef NO_TIMING
lbajardsilogic@0 60 ProfilePair &pair(m_profiles[id]);
lbajardsilogic@0 61 ++pair.first;
lbajardsilogic@0 62 pair.second.first += time;
lbajardsilogic@0 63 pair.second.second = pair.second.second + rt;
lbajardsilogic@0 64
lbajardsilogic@0 65 TimePair &lastPair(m_lastCalls[id]);
lbajardsilogic@0 66 lastPair.first = time;
lbajardsilogic@0 67 lastPair.second = rt;
lbajardsilogic@0 68
lbajardsilogic@0 69 TimePair &worstPair(m_worstCalls[id]);
lbajardsilogic@0 70 if (time > worstPair.first) {
lbajardsilogic@0 71 worstPair.first = time;
lbajardsilogic@0 72 }
lbajardsilogic@0 73 if (rt > worstPair.second) {
lbajardsilogic@0 74 worstPair.second = rt;
lbajardsilogic@0 75 }
lbajardsilogic@0 76 #endif
lbajardsilogic@0 77 }
lbajardsilogic@0 78
lbajardsilogic@0 79 void Profiles::dump() const
lbajardsilogic@0 80 {
lbajardsilogic@0 81 #ifndef NO_TIMING
lbajardsilogic@0 82
lbajardsilogic@0 83 fprintf(stderr, "Profiling points:\n");
lbajardsilogic@0 84
lbajardsilogic@0 85 fprintf(stderr, "\nBy name:\n");
lbajardsilogic@0 86
lbajardsilogic@0 87 typedef std::set<const char *, std::less<std::string> > StringSet;
lbajardsilogic@0 88
lbajardsilogic@0 89 StringSet profileNames;
lbajardsilogic@0 90 for (ProfileMap::const_iterator i = m_profiles.begin();
lbajardsilogic@0 91 i != m_profiles.end(); ++i) {
lbajardsilogic@0 92 profileNames.insert(i->first);
lbajardsilogic@0 93 }
lbajardsilogic@0 94
lbajardsilogic@0 95 for (StringSet::const_iterator i = profileNames.begin();
lbajardsilogic@0 96 i != profileNames.end(); ++i) {
lbajardsilogic@0 97
lbajardsilogic@0 98 ProfileMap::const_iterator j = m_profiles.find(*i);
lbajardsilogic@0 99
lbajardsilogic@0 100 if (j == m_profiles.end()) continue;
lbajardsilogic@0 101
lbajardsilogic@0 102 const ProfilePair &pp(j->second);
lbajardsilogic@0 103
lbajardsilogic@0 104 fprintf(stderr, "%s(%d):\n", *i, pp.first);
lbajardsilogic@0 105
lbajardsilogic@0 106 fprintf(stderr, "\tCPU: \t%.9g ms/call \t[%d ms total]\n",
lbajardsilogic@0 107 (((double)pp.second.first * 1000.0 /
lbajardsilogic@0 108 (double)pp.first) / CLOCKS_PER_SEC),
lbajardsilogic@0 109 int((pp.second.first * 1000.0) / CLOCKS_PER_SEC));
lbajardsilogic@0 110
lbajardsilogic@0 111 fprintf(stderr, "\tReal: \t%s ms \t[%s ms total]\n",
lbajardsilogic@0 112 ((pp.second.second / pp.first) * 1000).toString().c_str(),
lbajardsilogic@0 113 (pp.second.second * 1000).toString().c_str());
lbajardsilogic@0 114
lbajardsilogic@0 115 WorstCallMap::const_iterator k = m_worstCalls.find(*i);
lbajardsilogic@0 116 if (k == m_worstCalls.end()) continue;
lbajardsilogic@0 117
lbajardsilogic@0 118 const TimePair &wc(k->second);
lbajardsilogic@0 119
lbajardsilogic@0 120 fprintf(stderr, "\tWorst:\t%s ms/call \t[%d ms CPU]\n",
lbajardsilogic@0 121 (wc.second * 1000).toString().c_str(),
lbajardsilogic@0 122 int((wc.first * 1000.0) / CLOCKS_PER_SEC));
lbajardsilogic@0 123 }
lbajardsilogic@0 124
lbajardsilogic@0 125 typedef std::multimap<RealTime, const char *> TimeRMap;
lbajardsilogic@0 126 typedef std::multimap<int, const char *> IntRMap;
lbajardsilogic@0 127
lbajardsilogic@0 128 TimeRMap totmap, avgmap, worstmap;
lbajardsilogic@0 129 IntRMap ncallmap;
lbajardsilogic@0 130
lbajardsilogic@0 131 for (ProfileMap::const_iterator i = m_profiles.begin();
lbajardsilogic@0 132 i != m_profiles.end(); ++i) {
lbajardsilogic@0 133 totmap.insert(TimeRMap::value_type(i->second.second.second, i->first));
lbajardsilogic@0 134 avgmap.insert(TimeRMap::value_type(i->second.second.second /
lbajardsilogic@0 135 i->second.first, i->first));
lbajardsilogic@0 136 ncallmap.insert(IntRMap::value_type(i->second.first, i->first));
lbajardsilogic@0 137 }
lbajardsilogic@0 138
lbajardsilogic@0 139 for (WorstCallMap::const_iterator i = m_worstCalls.begin();
lbajardsilogic@0 140 i != m_worstCalls.end(); ++i) {
lbajardsilogic@0 141 worstmap.insert(TimeRMap::value_type(i->second.second,
lbajardsilogic@0 142 i->first));
lbajardsilogic@0 143 }
lbajardsilogic@0 144
lbajardsilogic@0 145
lbajardsilogic@0 146 fprintf(stderr, "\nBy total:\n");
lbajardsilogic@0 147 for (TimeRMap::const_iterator i = totmap.end(); i != totmap.begin(); ) {
lbajardsilogic@0 148 --i;
lbajardsilogic@0 149 fprintf(stderr, "%-40s %s ms\n", i->second,
lbajardsilogic@0 150 (i->first * 1000).toString().c_str());
lbajardsilogic@0 151 }
lbajardsilogic@0 152
lbajardsilogic@0 153 fprintf(stderr, "\nBy average:\n");
lbajardsilogic@0 154 for (TimeRMap::const_iterator i = avgmap.end(); i != avgmap.begin(); ) {
lbajardsilogic@0 155 --i;
lbajardsilogic@0 156 fprintf(stderr, "%-40s %s ms\n", i->second,
lbajardsilogic@0 157 (i->first * 1000).toString().c_str());
lbajardsilogic@0 158 }
lbajardsilogic@0 159
lbajardsilogic@0 160 fprintf(stderr, "\nBy worst case:\n");
lbajardsilogic@0 161 for (TimeRMap::const_iterator i = worstmap.end(); i != worstmap.begin(); ) {
lbajardsilogic@0 162 --i;
lbajardsilogic@0 163 fprintf(stderr, "%-40s %s ms\n", i->second,
lbajardsilogic@0 164 (i->first * 1000).toString().c_str(), i->second);
lbajardsilogic@0 165 }
lbajardsilogic@0 166
lbajardsilogic@0 167 fprintf(stderr, "\nBy number of calls:\n");
lbajardsilogic@0 168 for (IntRMap::const_iterator i = ncallmap.end(); i != ncallmap.begin(); ) {
lbajardsilogic@0 169 --i;
lbajardsilogic@0 170 fprintf(stderr, "%-40s %d\n", i->second, i->first);
lbajardsilogic@0 171 }
lbajardsilogic@0 172
lbajardsilogic@0 173 #endif
lbajardsilogic@0 174 }
lbajardsilogic@0 175
lbajardsilogic@0 176 #ifndef NO_TIMING
lbajardsilogic@0 177
lbajardsilogic@0 178 Profiler::Profiler(const char* c, bool showOnDestruct)
lbajardsilogic@0 179 : m_c(c),
lbajardsilogic@0 180 m_showOnDestruct(showOnDestruct)
lbajardsilogic@0 181 {
lbajardsilogic@0 182 m_startCPU = clock();
lbajardsilogic@0 183
lbajardsilogic@0 184 struct timeval tv;
lbajardsilogic@0 185 (void)gettimeofday(&tv, 0);
lbajardsilogic@0 186 m_startTime = RealTime::fromTimeval(tv);
lbajardsilogic@0 187 }
lbajardsilogic@0 188
lbajardsilogic@0 189 void
lbajardsilogic@0 190 Profiler::update() const
lbajardsilogic@0 191 {
lbajardsilogic@0 192 clock_t elapsedCPU = clock() - m_startCPU;
lbajardsilogic@0 193
lbajardsilogic@0 194 struct timeval tv;
lbajardsilogic@0 195 (void)gettimeofday(&tv, 0);
lbajardsilogic@0 196 RealTime elapsedTime = RealTime::fromTimeval(tv) - m_startTime;
lbajardsilogic@0 197
lbajardsilogic@0 198 cerr << "Profiler : id = " << m_c
lbajardsilogic@0 199 << " - elapsed so far = " << ((elapsedCPU * 1000) / CLOCKS_PER_SEC)
lbajardsilogic@0 200 << "ms CPU, " << elapsedTime << " real" << endl;
lbajardsilogic@0 201 }
lbajardsilogic@0 202
lbajardsilogic@0 203 Profiler::~Profiler()
lbajardsilogic@0 204 {
lbajardsilogic@0 205 clock_t elapsedCPU = clock() - m_startCPU;
lbajardsilogic@0 206
lbajardsilogic@0 207 struct timeval tv;
lbajardsilogic@0 208 (void)gettimeofday(&tv, 0);
lbajardsilogic@0 209 RealTime elapsedTime = RealTime::fromTimeval(tv) - m_startTime;
lbajardsilogic@0 210
lbajardsilogic@0 211 Profiles::getInstance()->accumulate(m_c, elapsedCPU, elapsedTime);
lbajardsilogic@0 212
lbajardsilogic@0 213 if (m_showOnDestruct)
lbajardsilogic@0 214 cerr << "Profiler : id = " << m_c
lbajardsilogic@0 215 << " - elapsed = " << ((elapsedCPU * 1000) / CLOCKS_PER_SEC)
lbajardsilogic@0 216 << "ms CPU, " << elapsedTime << " real" << endl;
lbajardsilogic@0 217 }
lbajardsilogic@0 218
lbajardsilogic@0 219 #endif
lbajardsilogic@0 220