forked from qt-creator/qt-creator
QmlProfiler: Send loaded events in batches of about 1024
This significantly reduces the number of signals necessary when loading traces. The overhead of queueing those signals across threads was responsible for up to 80% of the time required to load a trace. Change-Id: I461a2ef9944b0be102a29f8ed6b2b3f2f59f3c0f Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -154,6 +154,15 @@ void QmlProfilerDataModel::addEvent(const QmlEvent &event)
|
|||||||
d->eventStream << event;
|
d->eventStream << event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QmlProfilerDataModel::addEvents(const QVector<QmlEvent> &events)
|
||||||
|
{
|
||||||
|
Q_D(QmlProfilerDataModel);
|
||||||
|
for (const QmlEvent &event : events) {
|
||||||
|
d->modelManager->dispatch(event, d->eventTypes[event.typeIndex()]);
|
||||||
|
d->eventStream << event;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QmlProfilerDataModel::clear()
|
void QmlProfilerDataModel::clear()
|
||||||
{
|
{
|
||||||
Q_D(QmlProfilerDataModel);
|
Q_D(QmlProfilerDataModel);
|
||||||
|
@@ -52,6 +52,7 @@ public:
|
|||||||
void clear();
|
void clear();
|
||||||
bool isEmpty() const;
|
bool isEmpty() const;
|
||||||
void addEvent(const QmlEvent &event);
|
void addEvent(const QmlEvent &event);
|
||||||
|
void addEvents(const QVector<QmlEvent> &events);
|
||||||
void replayEvents(qint64 startTime, qint64 endTime,
|
void replayEvents(qint64 startTime, qint64 endTime,
|
||||||
QmlProfilerModelManager::EventLoader loader) const;
|
QmlProfilerModelManager::EventLoader loader) const;
|
||||||
void finalize();
|
void finalize();
|
||||||
|
@@ -378,8 +378,8 @@ void QmlProfilerModelManager::load(const QString &filename)
|
|||||||
connect(reader, &QmlProfilerFileReader::notesLoaded,
|
connect(reader, &QmlProfilerFileReader::notesLoaded,
|
||||||
d->notesModel, &QmlProfilerNotesModel::setNotes);
|
d->notesModel, &QmlProfilerNotesModel::setNotes);
|
||||||
|
|
||||||
connect(reader, &QmlProfilerFileReader::qmlEventLoaded,
|
connect(reader, &QmlProfilerFileReader::qmlEventsLoaded,
|
||||||
d->model, &QmlProfilerDataModel::addEvent);
|
d->model, &QmlProfilerDataModel::addEvents);
|
||||||
|
|
||||||
connect(reader, &QmlProfilerFileReader::success, this, [this, reader]() {
|
connect(reader, &QmlProfilerFileReader::success, this, [this, reader]() {
|
||||||
d->traceTime->setTime(reader->traceStart(), reader->traceEnd());
|
d->traceTime->setTime(reader->traceStart(), reader->traceEnd());
|
||||||
|
@@ -123,7 +123,7 @@ QmlProfilerFileReader::QmlProfilerFileReader(QObject *parent) :
|
|||||||
m_loadedFeatures(0)
|
m_loadedFeatures(0)
|
||||||
{
|
{
|
||||||
static int meta[] = {
|
static int meta[] = {
|
||||||
qRegisterMetaType<QmlEvent>(),
|
qRegisterMetaType<QVector<QmlEvent> >(),
|
||||||
qRegisterMetaType<QVector<QmlEventType> >(),
|
qRegisterMetaType<QVector<QmlEventType> >(),
|
||||||
qRegisterMetaType<QVector<QmlNote> >()
|
qRegisterMetaType<QVector<QmlNote> >()
|
||||||
};
|
};
|
||||||
@@ -248,7 +248,9 @@ bool QmlProfilerFileReader::loadQzt(QIODevice *device)
|
|||||||
emit notesLoaded(m_notes);
|
emit notesLoaded(m_notes);
|
||||||
updateProgress(device);
|
updateProgress(device);
|
||||||
|
|
||||||
QmlEvent event;
|
const int eventBufferLength = 1024;
|
||||||
|
QVector<QmlEvent> eventBuffer(eventBufferLength);
|
||||||
|
int eventBufferIndex = 0;
|
||||||
while (!stream.atEnd()) {
|
while (!stream.atEnd()) {
|
||||||
stream >> data;
|
stream >> data;
|
||||||
buffer.setData(qUncompress(data));
|
buffer.setData(qUncompress(data));
|
||||||
@@ -256,6 +258,7 @@ bool QmlProfilerFileReader::loadQzt(QIODevice *device)
|
|||||||
while (!buffer.atEnd()) {
|
while (!buffer.atEnd()) {
|
||||||
if (isCanceled())
|
if (isCanceled())
|
||||||
return false;
|
return false;
|
||||||
|
QmlEvent &event = eventBuffer[eventBufferIndex];
|
||||||
bufferStream >> event;
|
bufferStream >> event;
|
||||||
if (bufferStream.status() == QDataStream::Ok) {
|
if (bufferStream.status() == QDataStream::Ok) {
|
||||||
if (event.typeIndex() >= m_eventTypes.length()) {
|
if (event.typeIndex() >= m_eventTypes.length()) {
|
||||||
@@ -263,7 +266,6 @@ bool QmlProfilerFileReader::loadQzt(QIODevice *device)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_loadedFeatures |= (1ULL << m_eventTypes[event.typeIndex()].feature());
|
m_loadedFeatures |= (1ULL << m_eventTypes[event.typeIndex()].feature());
|
||||||
emit qmlEventLoaded(event);
|
|
||||||
} else if (bufferStream.status() == QDataStream::ReadPastEnd) {
|
} else if (bufferStream.status() == QDataStream::ReadPastEnd) {
|
||||||
break; // Apparently EOF is a character so we end up here after the last event.
|
break; // Apparently EOF is a character so we end up here after the last event.
|
||||||
} else if (bufferStream.status() == QDataStream::ReadCorruptData) {
|
} else if (bufferStream.status() == QDataStream::ReadCorruptData) {
|
||||||
@@ -272,10 +274,16 @@ bool QmlProfilerFileReader::loadQzt(QIODevice *device)
|
|||||||
} else {
|
} else {
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
if (++eventBufferIndex == eventBufferLength) {
|
||||||
|
emit qmlEventsLoaded(eventBuffer);
|
||||||
|
eventBufferIndex = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buffer.close();
|
buffer.close();
|
||||||
updateProgress(device);
|
updateProgress(device);
|
||||||
}
|
}
|
||||||
|
eventBuffer.resize(eventBufferIndex);
|
||||||
|
emit qmlEventsLoaded(eventBuffer);
|
||||||
emit success();
|
emit success();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -499,8 +507,7 @@ void QmlProfilerFileReader::loadEvents(QXmlStreamReader &stream)
|
|||||||
std::sort(events.begin(), events.end(), [](const QmlEvent &a, const QmlEvent &b) {
|
std::sort(events.begin(), events.end(), [](const QmlEvent &a, const QmlEvent &b) {
|
||||||
return a.timestamp() < b.timestamp();
|
return a.timestamp() < b.timestamp();
|
||||||
});
|
});
|
||||||
foreach (const QmlEvent &event, events)
|
emit qmlEventsLoaded(events);
|
||||||
emit qmlEventLoaded(event);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -62,7 +62,7 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void typesLoaded(const QVector<QmlProfiler::QmlEventType> &types);
|
void typesLoaded(const QVector<QmlProfiler::QmlEventType> &types);
|
||||||
void notesLoaded(const QVector<QmlProfiler::QmlNote> ¬es);
|
void notesLoaded(const QVector<QmlProfiler::QmlNote> ¬es);
|
||||||
void qmlEventLoaded(const QmlProfiler::QmlEvent &event);
|
void qmlEventsLoaded(const QVector<QmlProfiler::QmlEvent> &event);
|
||||||
void error(const QString &error);
|
void error(const QString &error);
|
||||||
void success();
|
void success();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user