Go to file
Milian Wolff 8619214c5e Optimize QMetaObject::activate.
The code is restructured to only loop over the non-empty connection
lists. This can be checked early while the mutex is locked already,
thus removing mutex lock/unlock calls that were done previously just
to realize the allsignals list is empty and can be skipped.

Additionally, at the very end of the loop over the last signal
connection list, the mutex was acquired even though it doesn't need
to be as we will quit the loop anyways.

This patch leverages these facts to remove the mutex locks which alone
has a considerable impact on the corresponding signal/slot benchmark.
The instruction count goes down by ca. 13%, while cycle count and
runtime drop by about 29%.

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":
     0.00000362 msecs per iteration (total: 362, iterations: 100000000)
     14.05652884 CPU cycles per iteration (total: 1,405,652,884, iterations: 100000000)
     21.00585673 instructions per iteration (total: 2,100,585,673, iterations: 100000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(single signal/slot)
RESULT : QObjectBenchmark::signal_slot_benchmark():"single signal/slot":
     0.00004709 msecs per iteration (total: 4,709, iterations: 100000000)
     183.75943370 CPU cycles per iteration (total: 18,375,943,371, iterations: 100000000)
     362.08604759 instructions per iteration (total: 36,208,604,760, iterations: 100000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(multi signal/slot)
RESULT : QObjectBenchmark::signal_slot_benchmark():"multi signal/slot":
     0.00004965 msecs per iteration (total: 4,965, iterations: 100000000)
     183.54556242 CPU cycles per iteration (total: 18,354,556,243, iterations: 100000000)
     362.07734835 instructions per iteration (total: 36,207,734,835, iterations: 100000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(unconnected signal)
RESULT : QObjectBenchmark::signal_slot_benchmark():"unconnected signal":
     0.00000752 msecs per iteration (total: 752, iterations: 100000000)
     30.08781366 CPU cycles per iteration (total: 3,008,781,367, iterations: 100000000)
     92.01520465 instructions per iteration (total: 9,201,520,466, iterations: 100000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(single signal/ptr)
RESULT : QObjectBenchmark::signal_slot_benchmark():"single signal/ptr":
     0.00005620 msecs per iteration (total: 5,620, iterations: 100000000)
     219.24739264 CPU cycles per iteration (total: 21,924,739,265, iterations: 100000000)
     327.08675555 instructions per iteration (total: 32,708,675,556, iterations: 100000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(functor)
RESULT : QObjectBenchmark::signal_slot_benchmark():"functor":
     0.00005852 msecs per iteration (total: 5,852, iterations: 100000000)
     218.45401359 CPU cycles per iteration (total: 21,845,401,360, iterations: 100000000)
     328.08472410 instructions per iteration (total: 32,808,472,410, iterations: 100000000)
PASS   : QObjectBenchmark::cleanupTestCase()
Totals: 8 passed, 0 failed, 0 skipped, 0 blacklisted, 44469ms
********* 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":
     0.00000361 msecs per iteration (total: 361, iterations: 100000000)
     14.01854817 CPU cycles per iteration (total: 1,401,854,818, iterations: 100000000)
     21.00532932 instructions per iteration (total: 2,100,532,933, iterations: 100000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(single signal/slot)
RESULT : QObjectBenchmark::signal_slot_benchmark():"single signal/slot":
     0.00003398 msecs per iteration (total: 3,398, iterations: 100000000)
     132.52735104 CPU cycles per iteration (total: 13,252,735,104, iterations: 100000000)
     314.04965106 instructions per iteration (total: 31,404,965,107, iterations: 100000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(multi signal/slot)
RESULT : QObjectBenchmark::signal_slot_benchmark():"multi signal/slot":
     0.00003448 msecs per iteration (total: 3,448, iterations: 100000000)
     133.63623046 CPU cycles per iteration (total: 13,363,623,046, iterations: 100000000)
     314.04952237 instructions per iteration (total: 31,404,952,238, iterations: 100000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(unconnected signal)
RESULT : QObjectBenchmark::signal_slot_benchmark():"unconnected signal":
     0.00000747 msecs per iteration (total: 747, iterations: 100000000)
     29.02349389 CPU cycles per iteration (total: 2,902,349,390, iterations: 100000000)
     92.01088221 instructions per iteration (total: 9,201,088,222, iterations: 100000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(single signal/ptr)
RESULT : QObjectBenchmark::signal_slot_benchmark():"single signal/ptr":
     0.00004350 msecs per iteration (total: 4,350, iterations: 100000000)
     167.83581885 CPU cycles per iteration (total: 16,783,581,885, iterations: 100000000)
     279.06426656 instructions per iteration (total: 27,906,426,657, iterations: 100000000)
PASS   : QObjectBenchmark::signal_slot_benchmark(functor)
RESULT : QObjectBenchmark::signal_slot_benchmark():"functor":
     0.00004337 msecs per iteration (total: 4,337, iterations: 100000000)
     170.45074743 CPU cycles per iteration (total: 17,045,074,743, iterations: 100000000)
     280.06267229 instructions per iteration (total: 28,006,267,229, iterations: 100000000)
PASS   : QObjectBenchmark::cleanupTestCase()
Totals: 8 passed, 0 failed, 0 skipped, 0 blacklisted, 33228ms
********* Finished testing of QObjectBenchmark *********

Change-Id: I6f79fd68ae7a07d9b439ca047bf1f53c83751d45
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
2016-03-03 09:55:56 +00:00
bin Add Intel copyright to files that Intel has had non-trivial contribution 2016-01-21 22:44:21 +00:00
config.tests Merge remote-tracking branch 'origin/5.6' into 5.7 2016-02-18 20:50:35 +01:00
dist Update the Qt 5.5.1 changelog for qtbase 2015-09-23 06:49:28 +00:00
doc Merge remote-tracking branch 'origin/5.6' into 5.7 2016-02-24 13:31:14 +01:00
examples Merge remote-tracking branch 'origin/5.6' into dev 2016-02-11 08:25:04 +01:00
lib Purge all fonts 2015-08-18 19:59:14 +00:00
mkspecs Merge remote-tracking branch 'origin/5.7' into dev 2016-03-01 08:23:55 +01:00
qmake qmake: restore nothrow move special members 2016-02-26 16:57:26 +00:00
src Optimize QMetaObject::activate. 2016-03-03 09:55:56 +00:00
tests Fix QTextEdit/QQuickTextEdit undo bug - Part #2 2016-03-02 16:00:02 +00:00
tools Remove LGPLv2 as a license option in configure 2016-02-15 14:55:32 +00:00
util Merge remote-tracking branch 'origin/5.6' into dev 2016-02-02 15:57:44 +01:00
.gitattributes Update the git-archive export options 2012-09-07 15:39:31 +02:00
.gitignore rewrite qtAddToolEnv() 2016-01-08 09:36:13 +00:00
.qmake.conf Bump version 2016-02-24 12:50:05 +01:00
.tag Update the git-archive export options 2012-09-07 15:39:31 +02:00
configure Merge remote-tracking branch 'origin/5.7' into dev 2016-03-01 08:23:55 +01:00
configure.bat Add initial clang-cl support to Qt 2016-02-11 12:54:06 +00:00
header.BSD Add new license header templates and license files 2016-01-14 20:43:46 +00:00
header.BSD-OLD Add new license header templates and license files 2016-01-14 20:43:46 +00:00
header.COMM Add header template for commercial only modules 2015-10-19 10:37:18 +00:00
header.FDL Add new license header templates and license files 2016-01-14 20:43:46 +00:00
header.FDL-OLD Add new license header templates and license files 2016-01-14 20:43:46 +00:00
header.GPL Add new license header templates and license files 2016-01-14 20:43:46 +00:00
header.GPL-EXCEPT Add new license header templates and license files 2016-01-14 20:43:46 +00:00
header.LGPL Add new license header templates and license files 2016-01-14 20:43:46 +00:00
header.LGPL3 Update copyright headers 2015-02-11 06:49:51 +00:00
header.LGPL3-COMM Update copyright headers 2015-02-11 06:49:51 +00:00
header.LGPL21 Update copyright headers 2015-02-11 06:49:51 +00:00
header.LGPL-NOGPL2 Add new license header templates and license files 2016-01-14 20:43:46 +00:00
header.LGPL-ONLY Update copyright headers 2015-02-11 06:49:51 +00:00
INSTALL Doc: Update links in INSTALL file 2015-02-16 09:06:41 +00:00
LGPL_EXCEPTION.txt Update copyright headers 2015-02-11 06:49:51 +00:00
LICENSE.FDL Initial import from the monolithic Qt. 2011-04-27 12:05:43 +02:00
LICENSE.GPL2 Add new license header templates and license files 2016-01-14 20:43:46 +00:00
LICENSE.GPL3 Add new license header templates and license files 2016-01-14 20:43:46 +00:00
LICENSE.GPL3-EXCEPT Add new license header templates and license files 2016-01-14 20:43:46 +00:00
LICENSE.GPLv3 fix up license references 2015-08-13 11:13:09 +00:00
LICENSE.LGPL3 Add new license header templates and license files 2016-01-14 20:43:46 +00:00
LICENSE.LGPLv3 Bump copyright year to 2016 2016-01-29 13:30:04 +00:00
LICENSE.LGPLv21 Bump copyright year to 2016 2016-01-29 13:30:04 +00:00
LICENSE.PREVIEW.COMMERCIAL Add new license header templates and license files 2016-01-14 20:43:46 +00:00
qtbase.pro Merge remote-tracking branch 'origin/5.6' into dev 2015-11-18 09:01:51 +01:00
sync.profile make a proper header-only module for QtZlib 2015-11-17 20:22:17 +00:00