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

_______________________________________________
Development mailing list
[email protected]
http://lists.qt-project.org/mailman/listinfo/development

Reply via email to