Performance tuning

pull/653/head
Michael Zanetti 2021-08-24 14:45:36 +02:00
parent 417edc4e58
commit 973d3f1a4e
6 changed files with 50 additions and 36 deletions

View File

@ -159,6 +159,7 @@ void LogsModel::setTypeIds(const QStringList &typeIds)
beginResetModel();
qDeleteAll(m_list);
m_list.clear();
m_generatedEntries = 0;
endResetModel();
fetchMore();
}
@ -256,7 +257,7 @@ LogEntry *LogsModel::findClosest(const QDateTime &dateTime)
void LogsModel::logsReply(int /*commandId*/, const QVariantMap &data)
{
int offset = data.value("offset").toInt();
int offset = data.value("offset").toInt() + m_generatedEntries;
int count = data.value("count").toInt();
// qDebug() << qUtf8Printable(QJsonDocument::fromVariant(data).toJson());
@ -266,9 +267,6 @@ void LogsModel::logsReply(int /*commandId*/, const QVariantMap &data)
foreach (const QVariant &logEntryVariant, logEntries) {
QVariantMap entryMap = logEntryVariant.toMap();
QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong());
if (!m_viewStartTime.isNull() && timeStamp < m_viewStartTime) {
continue;
}
QString thingId = entryMap.value("thingId").toString();
QString typeId = entryMap.value("typeId").toString();
QMetaEnum sourceEnum = QMetaEnum::fromType<LogEntry::LoggingSource>();
@ -277,8 +275,19 @@ void LogsModel::logsReply(int /*commandId*/, const QVariantMap &data)
LogEntry::LoggingEventType loggingEventType = static_cast<LogEntry::LoggingEventType>(loggingEventTypeEnum.keyToValue(entryMap.value("eventType").toByteArray()));
QVariant value = loggingEventType == LogEntry::LoggingEventTypeActiveChange ? entryMap.value("active").toBool() : entryMap.value("value");
QString errorCode = entryMap.value("errorCode").toString();
bool stopProcessing = false;
if (m_viewStartTime.isValid() && timeStamp.addSecs(-60) < m_viewStartTime) {
timeStamp = m_viewStartTime.addSecs(-60);
stopProcessing = true;
m_generatedEntries++;
}
LogEntry *entry = new LogEntry(timeStamp, value, thingId, typeId, loggingSource, loggingEventType, errorCode, this);
newBlock.append(entry);
// qCDebug(dcLogEngine()) << objectName() << "adding entry at" << timeStamp << m_viewStartTime;
if (stopProcessing) {
break;
}
}
// qCDebug(dcLogEngine()) << objectName() << "Received logs from" << offset << "to" << offset + count << "Actual count:" << newBlock.count();
@ -363,7 +372,7 @@ void LogsModel::fetchMore(const QModelIndex &parent)
}
params.insert("limit", m_blockSize);
params.insert("offset", m_list.count());
params.insert("offset", m_list.count() - m_generatedEntries);
// qDebug() << "Fetching logs from" << m_startTime.toString() << "to" << m_endTime.toString() << "with offset" << m_list.count() << "and limit" << m_blockSize;

View File

@ -133,6 +133,8 @@ protected:
bool m_canFetchMore = true;
int m_generatedEntries = 0;
};
#endif // LOGSMODEL_H

View File

@ -163,12 +163,21 @@ void XYSeriesAdapter::logEntryAdded(LogEntry *entry)
int idx = entry->timestamp().secsTo(m_newestSample) / m_sampleRate;
if (idx > m_samples.count()) {
qCWarning(dcLogEngine) << "Overflowing integer size for XYSeriesAdapter!";
qCWarning(dcLogEngine) << objectName() << "Overflowing integer size for XYSeriesAdapter!";
return;
}
Sample *sample = m_samples.at(static_cast<int>(idx));
LogEntry *oldLast = sample->entries.count() > 0 ? sample->entries.last() : nullptr;
sample->entries.append(entry);
// qCDebug(dcLogEngine()) << objectName() << "Inserting sample at:" << idx << entry->timestamp();
Sample *sample = m_samples.at(idx);
LogEntry *oldLast = nullptr;
// In theory we'd need to insert sorted, but only the last one actually matters for subsequent samples
// For the current sample we're calculating the median anyways, so just append/prepend t be a bit faster
if (sample->entries.count() > 0 && sample->entries.last()->timestamp() < entry->timestamp()) {
oldLast = sample->entries.last();
sample->entries.append(entry);
} else {
sample->entries.prepend(entry);
}
LogEntry *newLast = sample->entries.last();
qreal value = calculateSampleValue(idx);
m_series->replace(idx, sample->timestamp.toMSecsSinceEpoch(), value);
@ -189,7 +198,7 @@ void XYSeriesAdapter::logEntryAdded(LogEntry *entry)
for (int i = idx - 1; i >= 0; i--) {
Sample *nextSample = m_samples.at(i);
if (nextSample->startingPoint == oldLast) {
nextSample->startingPoint = entry;
nextSample->startingPoint = newLast;
qreal value = calculateSampleValue(i);
// qWarning() << "Updating" << i << value;
m_series->replace(i, nextSample->timestamp.toMSecsSinceEpoch(), value);

View File

@ -69,8 +69,8 @@ private:
class Sample {
public:
QDateTime timestamp; // The timestamp where this sample *ends*
QList<LogEntry*> entries; // all log entries in this sample, that is, from timestamp - m_sampleRate
LogEntry *startingPoint = nullptr; // the starting point for the same. Normally the last entry of the previous sample
QList<LogEntry*> entries; // all log entries in this sample, that is, from timestamp - smaple size to timestamp
LogEntry *startingPoint = nullptr; // the starting point for the sample. Normally the last entry of the previous sample
};
LogsModel* m_model = nullptr;
QtCharts::QXYSeries* m_series = nullptr;

View File

@ -48,8 +48,9 @@ ChartView {
property Thing rootMeter: null
property ThingsProxy meters: null
property int multiplier: 1
property string stateName: "totalEnergyConsumed"
readonly property State rootMeterTotalConsumedEnergyState: rootMeter ? rootMeter.stateByName("totalEnergyConsumed") : null
readonly property State rootMeterTotalEnergyState: rootMeter ? rootMeter.stateByName(stateName) : null
Connections {
target: meters
@ -69,29 +70,14 @@ ChartView {
pieSeries.clear();
d.sliceMap = {}
var unknownConsumerEnergy = 0;
if (rootMeter) {
unknownConsumerEnergy = rootMeter.stateByName("totalEnergyConsumed").value
}
if (rootMeter) {
var slice = pieSeries.append(qsTr("Unknown"), unknownConsumerEnergy)
slice.color = Style.accentColor
d.sliceMap[slice] = rootMeter
}
var unknownEnergy = rootMeterTotalEnergyState ? rootMeterTotalEnergyState.value : 0
for (var i = 0; i < meters.count; i++) {
var thing = meters.get(i);
var value = 0;
var totalConsumedStateType = thing.thingClass.stateTypes.findByName("totalEnergyConsumed")
if (totalConsumedStateType) {
var totalConsumedState = thing.states.getState(totalConsumedStateType.id)
value = value + (totalConsumedState.value * root.multiplier)
}
var totalProducedStateType = thing.thingClass.stateTypes.findByName("totalEnergyProduced")
if (totalProducedStateType) {
var totalProducedState = thing.states.getState(totalProducedStateType.id)
value = value - (totalProducedState.value * root.multiplier)
var energyState = thing.stateByName(root.stateName)
if (energyState) {
value += energyState.value
}
var slice = pieSeries.append(thing.name, Math.max(0, value))
var color = Style.accentColor
@ -104,7 +90,13 @@ ChartView {
}
slice.color = color
d.sliceMap[slice] = thing
unknownConsumerEnergy -= value
unknownEnergy -= value
}
if (unknownEnergy > 0) {
var slice = pieSeries.append(qsTr("Unknown"), unknownEnergy)
slice.color = Style.accentColor
d.sliceMap[slice] = rootMeter
}
}
@ -128,8 +120,8 @@ ChartView {
font.pixelSize: app.largeFont
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
text: root.rootMeterTotalConsumedEnergyState
? root.rootMeterTotalConsumedEnergyState.value.toFixed(2)
text: root.rootMeterTotalEnergyState
? root.rootMeterTotalEnergyState.value.toFixed(2)
: Math.round(pieSeries.sum * 1000) / 1000
}

View File

@ -124,6 +124,7 @@ MainViewBase {
}
XYSeriesAdapter {
id: rootMeterSeriesAdapter
objectName: "Root meter adapter"
logsModel: rootMeterLogsModel
sampleRate: chartView.sampleRate
xySeries: rootMeterSeries
@ -197,6 +198,7 @@ MainViewBase {
}
property XYSeriesAdapter adapter: XYSeriesAdapter {
id: seriesAdapter
objectName: consumer.thing.name + " adapter"
logsModel: logsModel
sampleRate: chartView.sampleRate
xySeries: upperSeries
@ -441,8 +443,8 @@ MainViewBase {
rootMeter: root.rootMeter
meters: producers
title: qsTr("Total produced energy")
stateName: "totalEnergyProduced"
visible: root.rootMeter || producers.count > 0
multiplier: -1
}
}
}