annotate base/Profiler.cpp @ 1879:652c5360e682

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