Microoptimize QObject::activate.

This patch removes temporary variables that are not used in all cases.
This reduces the instruction count per iteration for the corresponding
benchmark by 1 or 2.

Before:

********* Start testing of QObjectBenchmark *********
Config: Using QtTest library 5.7.0, Qt 5.7.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 5.3.0)
PASS   : QObjectBenchmark::initTestCase()
PASS   : QObjectBenchmark::signal_slot_benchmark(simple function)
RESULT : QObjectBenchmark::signal_slot_benchmark():"simple function":
     21.0065466 instructions per iteration (total: 210,065,466, iterations: 10000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(single signal/slot)
RESULT : QObjectBenchmark::signal_slot_benchmark():"single signal/slot":
     405.0829559 instructions per iteration (total: 4,050,829,559, iterations: 10000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(multi signal/slot)
RESULT : QObjectBenchmark::signal_slot_benchmark():"multi signal/slot":
     405.0812465 instructions per iteration (total: 4,050,812,465, iterations: 10000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(unconnected signal)
RESULT : QObjectBenchmark::signal_slot_benchmark():"unconnected signal":
     104.0147348 instructions per iteration (total: 1,040,147,349, iterations: 10000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(single signal/ptr)
RESULT : QObjectBenchmark::signal_slot_benchmark():"single signal/ptr":
     369.1021099 instructions per iteration (total: 3,691,021,100, iterations: 10000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(functor)
RESULT : QObjectBenchmark::signal_slot_benchmark():"functor":
     370.0982862 instructions per iteration (total: 3,700,982,862, iterations: 10000000)
PASS   : QObjectBenchmark::cleanupTestCase()
Totals: 8 passed, 0 failed, 0 skipped, 0 blacklisted, 6036ms
********* Finished testing of QObjectBenchmark *********

After:

********* Start testing of QObjectBenchmark *********
Config: Using QtTest library 5.7.0, Qt 5.7.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 5.3.0)
PASS   : QObjectBenchmark::initTestCase()
PASS   : QObjectBenchmark::signal_slot_benchmark(simple function)
RESULT : QObjectBenchmark::signal_slot_benchmark():"simple function":
     21.0061664 instructions per iteration (total: 210,061,664, iterations: 10000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(single signal/slot)
RESULT : QObjectBenchmark::signal_slot_benchmark():"single signal/slot":
     403.0829161 instructions per iteration (total: 4,030,829,162, iterations: 10000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(multi signal/slot)
RESULT : QObjectBenchmark::signal_slot_benchmark():"multi signal/slot":
     403.0836305 instructions per iteration (total: 4,030,836,305, iterations: 10000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(unconnected signal)
RESULT : QObjectBenchmark::signal_slot_benchmark():"unconnected signal":
     104.0150038 instructions per iteration (total: 1,040,150,039, iterations: 10000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(single signal/ptr)
RESULT : QObjectBenchmark::signal_slot_benchmark():"single signal/ptr":
     368.0981987 instructions per iteration (total: 3,680,981,988, iterations: 10000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(functor)
RESULT : QObjectBenchmark::signal_slot_benchmark():"functor":
     369.1179429 instructions per iteration (total: 3,691,179,429, iterations: 10000000)
PASS   : QObjectBenchmark::cleanupTestCase()
Totals: 8 passed, 0 failed, 0 skipped, 0 blacklisted, 5975ms
********* Finished testing of QObjectBenchmark *********

Change-Id: Iba3bffbca5b58109816c8b1a7dea0796b18c8785
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
bb10
Milian Wolff 2016-02-14 16:24:13 +01:00
parent e1538b39bb
commit bd35260415
1 changed files with 5 additions and 5 deletions

View File

@ -3713,8 +3713,6 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
if (receiverInSameThread) {
sw.switchSender(receiver, sender, signal_index);
}
const QObjectPrivate::StaticMetaCallFunction callFunction = c->callFunction;
const int method_relative = c->method_relative;
if (c->isSlotObject) {
c->slotObj->ref();
QScopedPointer<QtPrivate::QSlotObjectBase, QSlotObjectBaseDeleter> obj(c->slotObj);
@ -3727,10 +3725,12 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
obj.reset();
locker.relock();
} else if (callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) {
} else if (c->callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) {
//we compare the vtable to make sure we are not in the destructor of the object.
locker.unlock();
const int methodIndex = c->method();
const int method_relative = c->method_relative;
const auto callFunction = c->callFunction;
locker.unlock();
if (qt_signal_spy_callback_set.slot_begin_callback != 0)
qt_signal_spy_callback_set.slot_begin_callback(receiver, methodIndex, argv ? argv : empty_argv);
@ -3740,7 +3740,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
qt_signal_spy_callback_set.slot_end_callback(receiver, methodIndex);
locker.relock();
} else {
const int method = method_relative + c->method_offset;
const int method = c->method_relative + c->method_offset;
locker.unlock();
if (qt_signal_spy_callback_set.slot_begin_callback != 0) {