diff options
author | Ulf Hermann <[email protected]> | 2018-03-23 10:56:31 +0100 |
---|---|---|
committer | Ulf Hermann <[email protected]> | 2018-04-16 07:16:35 +0000 |
commit | 87c12c4e1b762f890602ea603acc92bda1909e94 (patch) | |
tree | 2d5ed9b412c437c3c939b052ae6ec4516a231c4e /src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp | |
parent | 5784fce2449485b627327f88f96301298987941f (diff) |
QmlProfiler: Store statistics data in a saner way
We don't need to retain the durations after finalize(), and we can use
vectors instead of hashes, as we will cover almost all types anyway.
Vectors allow us to potentially use the position of an item in the data
as its row.
Change-Id: I2c09406f0e0a42f5f517f8444755b1664efb8f3b
Reviewed-by: Ulf Hermann <[email protected]>
Diffstat (limited to 'src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp')
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp | 92 |
1 files changed, 46 insertions, 46 deletions
diff --git a/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp b/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp index f4b9c931fae..a28647cbd0f 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp @@ -52,16 +52,16 @@ QString QmlProfilerStatisticsModel::nameForType(RangeType typeNumber) double QmlProfilerStatisticsModel::durationPercent(int typeId) const { - const QmlEventStats &global = m_data[-1]; - const QmlEventStats &stats = m_data[typeId]; - return double(stats.duration - stats.durationRecursive) / double(global.duration) * 100l; + return (typeId >= 0) + ? double(m_data[typeId].totalNonRecursive()) / double(m_rootDuration) * 100 + : 100; } double QmlProfilerStatisticsModel::durationSelfPercent(int typeId) const { - const QmlEventStats &global = m_data[-1]; - const QmlEventStats &stats = m_data[typeId]; - return double(stats.durationSelf) / double(global.duration) * 100l; + return (typeId >= 0) + ? (double(m_data[typeId].self) / double(m_rootDuration) * 100) + : 0; } QmlProfilerStatisticsModel::QmlProfilerStatisticsModel(QmlProfilerModelManager *modelManager) @@ -122,7 +122,8 @@ bool QmlProfilerStatisticsModel::isRestrictedToRange() const return m_modelManager->isRestrictedToRange(); } -const QHash<int, QmlProfilerStatisticsModel::QmlEventStats> &QmlProfilerStatisticsModel::getData() const +const QVector<QmlProfilerStatisticsModel::QmlEventStats> & +QmlProfilerStatisticsModel::getData() const { return m_data; } @@ -193,11 +194,11 @@ QString QmlProfilerStatisticsModel::summary(const QVector<int> &typeIds) const void QmlProfilerStatisticsModel::clear() { + m_rootDuration = 0; m_data.clear(); m_notes.clear(); m_callStack.clear(); m_compileStack.clear(); - m_durations.clear(); if (!m_calleesModel.isNull()) m_calleesModel->clear(); if (!m_callersModel.isNull()) @@ -256,42 +257,40 @@ void QmlProfilerStatisticsModel::loadEvent(const QmlEvent &event, const QmlEvent if (!m_acceptedTypes.contains(type.rangeType())) return; + const int typeIndex = event.typeIndex(); bool isRecursive = false; QStack<QmlEvent> &stack = type.rangeType() == Compiling ? m_compileStack : m_callStack; switch (event.rangeStage()) { case RangeStart: stack.push(event); + if (m_data.length() <= typeIndex) + m_data.resize(m_modelManager->numLoadedEventTypes()); break; case RangeEnd: { // update stats QTC_ASSERT(!stack.isEmpty(), return); - QTC_ASSERT(stack.top().typeIndex() == event.typeIndex(), return); - QmlEventStats *stats = &m_data[event.typeIndex()]; + QTC_ASSERT(stack.top().typeIndex() == typeIndex, return); + QmlEventStats &stats = m_data[typeIndex]; qint64 duration = event.timestamp() - stack.top().timestamp(); - stats->duration += duration; - stats->durationSelf += duration; - if (duration < stats->minTime) - stats->minTime = duration; - if (duration > stats->maxTime) - stats->maxTime = duration; - stats->calls++; - // for median computing - m_durations[event.typeIndex()].append(duration); + stats.total += duration; + stats.self += duration; + stats.durations.push_back(duration); stack.pop(); // recursion detection: check whether event was already in stack for (int ii = 0; ii < stack.size(); ++ii) { - if (stack.at(ii).typeIndex() == event.typeIndex()) { + if (stack.at(ii).typeIndex() == typeIndex) { isRecursive = true; - stats->durationRecursive += duration; + stats.recursive += duration; break; } } if (!stack.isEmpty()) - m_data[stack.top().typeIndex()].durationSelf -= duration; + m_data[stack.top().typeIndex()].self -= duration; else - m_data[-1].duration += duration; + m_rootDuration += duration; + break; } default: @@ -307,20 +306,8 @@ void QmlProfilerStatisticsModel::loadEvent(const QmlEvent &event, const QmlEvent void QmlProfilerStatisticsModel::finalize() { - // post-process: calc mean time, median time, percentoftime - for (QHash<int, QmlEventStats>::iterator it = m_data.begin(); it != m_data.end(); ++it) { - QVector<qint64> eventDurations = m_durations[it.key()]; - if (!eventDurations.isEmpty()) { - Utils::sort(eventDurations); - it->medianTime = eventDurations.at(eventDurations.count()/2); - } - } - - // insert root event - QmlEventStats &rootEvent = m_data[-1]; - rootEvent.minTime = rootEvent.maxTime = rootEvent.medianTime = rootEvent.duration; - rootEvent.durationSelf = 0; - rootEvent.calls = 1; + for (QmlEventStats &stats : m_data) + stats.finalize(); emit dataAvailable(); } @@ -346,15 +333,15 @@ QmlProfilerStatisticsRelativesModel::QmlProfilerStatisticsRelativesModel( this, &QmlProfilerStatisticsRelativesModel::dataAvailable); } -const QmlProfilerStatisticsRelativesModel::QmlStatisticsRelativesMap & +const QVector<QmlProfilerStatisticsRelativesModel::QmlStatisticsRelativesData> & QmlProfilerStatisticsRelativesModel::getData(int typeId) const { - QHash <int, QmlStatisticsRelativesMap>::ConstIterator it = m_data.find(typeId); + auto it = m_data.find(typeId); if (it != m_data.end()) { return it.value(); } else { - static const QmlStatisticsRelativesMap emptyMap; - return emptyMap; + static const QVector<QmlStatisticsRelativesData> emptyVector; + return emptyVector; } } @@ -363,6 +350,18 @@ const QVector<QmlEventType> &QmlProfilerStatisticsRelativesModel::getTypes() con return m_modelManager->eventTypes(); } +bool operator<(const QmlProfilerStatisticsRelativesModel::QmlStatisticsRelativesData &a, + const QmlProfilerStatisticsRelativesModel::QmlStatisticsRelativesData &b) +{ + return a.typeIndex < b.typeIndex; +} + +bool operator<(const QmlProfilerStatisticsRelativesModel::QmlStatisticsRelativesData &a, + int typeIndex) +{ + return a.typeIndex < typeIndex; +} + void QmlProfilerStatisticsRelativesModel::loadEvent(RangeType type, const QmlEvent &event, bool isRecursive) { @@ -379,15 +378,16 @@ void QmlProfilerStatisticsRelativesModel::loadEvent(RangeType type, const QmlEve int selfTypeIndex = (m_relation == QmlProfilerStatisticsCallers) ? event.typeIndex() : callerTypeIndex; - QmlStatisticsRelativesMap &relativesMap = m_data[selfTypeIndex]; - QmlStatisticsRelativesMap::Iterator it = relativesMap.find(relativeTypeIndex); - if (it != relativesMap.end()) { + QVector<QmlStatisticsRelativesData> &relatives = m_data[selfTypeIndex]; + auto it = std::lower_bound(relatives.begin(), relatives.end(), relativeTypeIndex); + if (it != relatives.end() && it->typeIndex == relativeTypeIndex) { it->calls++; it->duration += event.timestamp() - stack.top().startTime; it->isRecursive = isRecursive || it->isRecursive; } else { - relativesMap.insert(relativeTypeIndex, QmlStatisticsRelativesData( - event.timestamp() - stack.top().startTime, 1, isRecursive)); + relatives.insert(it, QmlStatisticsRelativesData( + event.timestamp() - stack.top().startTime, 1, relativeTypeIndex, + isRecursive)); } stack.pop(); break; |