[Development] Announcing moc_combine

Thiago Macieira thiago.macieira at intel.com
Sun May 29 18:05:07 CEST 2016


I've just pushed a feature[1] to moc that makes it process multiple headers at 
the same time, producing only one output file, and a second feature[2] that 
"precompiles" a header. Since moc is single-threaded, this often means more 
wall-clock time than the previous case, but it's always less CPU time:

                    CPU time (s)
Moc – before        11,56		
Moc – after	        4,33		

If you add that to the time to compile the moc output and to link, there's a 
definite gain.

                    Debug	Release	Release + LTO
Compile – before	30,05	23,71	22,35
Compile – after	    5,85	6,28	5,36
Link – before       31,27	24,15	110,57
Link – after        7,04	6,52	92,21

For the full build, the change in wall-clock (seconds, 2-core * 2 HT CPU) is 
small, but visible:

            Release	Release + LTO
Before      68,813	77,736
After       66,426	61,084

(note: the "before" numbers are *after* I removed the #includes, so they're 
slighty higher than the QtCore before all my changes)

This feature is optional. You can enable it for your module by doing:
   CONFIG += moc_combine

BUT (and of course there's a "but")

You can only enable it if you rid your module of Q_PRIVATE_SLOT first. Since 
this feature produces a single moc output for all headers, you can't have 
#include at the end of your files [exception: if you have only one such 
#include].

To get rid of the Q_PRIVATE_SLOTs, you can use the QObjectPrivate::connect 
overload that takes a QObjectPrivate pointer as third parameter. We can divide 
the porting in three groups:

1) easy/trivial:
- simple connect() statements (even supports Qt::UniqueConnection, provided 
   that you're connecting PMFs [note: there might be bugs!!])
- simple disconnect() statements where the four parameters match the same four 
  of the connect()
- QMetaObject::invokeMethod becoming QTimer::singleShot of 0 seconds

examples: [3] and [4]

2) doable:
- when there are disconnect()s that aren't trivial, in which case you need to 
  retain the QMetaObject::Connection result of the connect() call

example: [5]

3) hard:
- when you need to do a major refactoring of the internals because it depended 
  on QMetaMethod or something similar (see [6])
- when the front-end API requires modification too

[1] https://codereview.qt-project.org/160755
[2] https://codereview.qt-project.org/160756
[3] https://codereview.qt-project.org/160752
[4] https://codereview.qt-project.org/160753
[5] https://codereview.qt-project.org/#/c/160751/1/src/corelib/animation/
qanimationgroup_p.h
[6] https://codereview.qt-project.org/160758
-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center




More information about the Development mailing list