diff options
author | Robin Burchell <robin.burchell@collabora.com> | 2011-12-09 15:05:10 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-12-30 21:58:10 +0100 |
commit | 69a44f9cfc569f447567179279363e608b53ff49 (patch) | |
tree | 3dbe0e023b1ebeddde324a5a852f77adc1cc3035 /src | |
parent | 7f4c45390d4ad3f3fcff5faadfc2870624efa0cb (diff) |
Change event posting to use a QVector.
This provides a ~10% improvement to the newly introduced QCoreApplication
event_posting_benchmark (a simple synthetic benchmark of creating a bunch of
events, posting them, and sending the queue).
before:
********* Start testing of QCoreApplicationBenchmark *********
Config: Using QTest library 5.0.0, Qt 5.0.0
PASS : QCoreApplicationBenchmark::initTestCase()
RESULT : QCoreApplicationBenchmark::signal_slot_benchmark():"1000":
0.82 msecs per iteration (total: 53, iterations: 64)
RESULT : QCoreApplicationBenchmark::signal_slot_benchmark():"10000":
8.6 msecs per iteration (total: 69, iterations: 8)
RESULT : QCoreApplicationBenchmark::signal_slot_benchmark():"100000":
84 msecs per iteration (total: 84, iterations: 1)
RESULT : QCoreApplicationBenchmark::signal_slot_benchmark():"1000000":
874 msecs per iteration (total: 874, iterations: 1)
PASS : QCoreApplicationBenchmark::signal_slot_benchmark()
PASS : QCoreApplicationBenchmark::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped
********* Finished testing of QCoreApplicationBenchmark *********
after:
********* Start testing of QCoreApplicationBenchmark *********
Config: Using QTest library 5.0.0, Qt 5.0.0
PASS : QCoreApplicationBenchmark::initTestCase()
RESULT : QCoreApplicationBenchmark::event_posting_benchmark():"1000 events":
0.781 msecs per iteration (total: 100, iterations: 128)
RESULT : QCoreApplicationBenchmark::event_posting_benchmark():"10000 events":
7.8 msecs per iteration (total: 63, iterations: 8)
RESULT : QCoreApplicationBenchmark::event_posting_benchmark():"100000 events":
75 msecs per iteration (total: 75, iterations: 1)
RESULT : QCoreApplicationBenchmark::event_posting_benchmark():"1000000 events":
774 msecs per iteration (total: 774, iterations: 1)
PASS : QCoreApplicationBenchmark::event_posting_benchmark()
PASS : QCoreApplicationBenchmark::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped
********* Finished testing of QCoreApplicationBenchmark *********
Change-Id: Ibf56d9526b0a8cbaf171008da4104bb457628172
Reviewed-by: Sergio Ahumada <sergio.ahumada@nokia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 15 | ||||
-rw-r--r-- | src/corelib/thread/qthread_p.h | 14 |
2 files changed, 21 insertions, 8 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 6f26be2928..e105100e3e 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1405,9 +1405,18 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type if (!allowDeferredDelete) { // cannot send deferred delete if (!event_type && !receiver) { - // don't lose the event - data->postEventList.addEvent(pe); + // we must copy it first; we want to re-post the event + // with the event pointer intact, but we can't delay + // nulling the event ptr until after re-posting, as + // addEvent may invalidate pe. + QPostEvent pe_copy = pe; + + // null out the event so if sendPostedEvents recurses, it + // will ignore this one, as it's been re-posted. const_cast<QPostEvent &>(pe).event = 0; + + // re-post the copied event so it isn't lost + data->postEventList.addEvent(pe_copy); } continue; } @@ -1509,7 +1518,7 @@ void QCoreApplication::removePostedEvents(QObject *receiver, int eventType) const_cast<QPostEvent &>(pe).event = 0; } else if (!data->postEventList.recursion) { if (i != j) - data->postEventList.swap(i, j); + qSwap(data->postEventList[i], data->postEventList[j]); ++j; } } diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index bbaf664a2d..8be9f134ae 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -81,6 +81,8 @@ public: : receiver(r), event(e), priority(p) { } }; +Q_DECLARE_TYPEINFO(QPostEvent, Q_MOVABLE_TYPE); + inline bool operator<(int priority, const QPostEvent &pe) { return pe.priority < priority; @@ -92,7 +94,7 @@ inline bool operator<(const QPostEvent &pe, int priority) // This class holds the list of posted events. // The list has to be kept sorted by priority -class QPostEventList : public QList<QPostEvent> +class QPostEventList : public QVector<QPostEvent> { public: // recursion == recursion count for sendPostedEvents() @@ -106,12 +108,14 @@ public: QMutex mutex; inline QPostEventList() - : QList<QPostEvent>(), recursion(0), startOffset(0), insertionOffset(0) + : QVector<QPostEvent>(), recursion(0), startOffset(0), insertionOffset(0) { } void addEvent(const QPostEvent &ev) { int priority = ev.priority; - if (isEmpty() || last().priority >= priority) { + if (isEmpty() || + last().priority >= priority || + begin() + insertionOffset >= end()) { // optimization: we can simply append if the last event in // the queue has higher or equal priority append(ev); @@ -125,8 +129,8 @@ public: } private: //hides because they do not keep that list sorted. addEvent must be used - using QList<QPostEvent>::append; - using QList<QPostEvent>::insert; + using QVector<QPostEvent>::append; + using QVector<QPostEvent>::insert; }; #ifndef QT_NO_THREAD |