Prefer to use normalised signal/slot signatures



Some time ago I’ve talked with my Berlin office mates about the benefits of using normalised signal signatures in connect statements. That is, instead of

SIGNAL( rowsInserted( const QModelIndex &, int, const int ) )

write

SIGNAL(rowsInserted(QModelIndex,int,int))

That is, remove all dispensable whitespace, const-& , and top-level const . If you’re in doubt about how the normalised form of your signal or slot looks like, take a look at the string data in the moc-generated file. The signals and slots are listed with their normalised signatures there.

What was clear already then is that you’ll save a few bytes of string data if you use the shorter form. I was also expecting a zero-copy fast-path in QMetaObject::normalizedSignature() for the case of an already-normalised argument. I didn’t find it back then, and I put the issue on my to-do list to implement in Qt.

But I’ve just stumbled over the code of QObject::connect() . If you look there, you’ll see that not using the normalised form has a rather severe performance penalty:

int signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false); if (signal_index < 0) { // check for normalized signatures tmp_signal_name = QMetaObject::normalizedSignature(signal - 1); signal = tmp_signal_name.constData() + 1; smeta = sender->metaObject(); signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false); }

Lookup is first attempted with the signature as-is, and only if that fails is QMetaObject::normalizedSignature() called.

That means, when using non-normalised signal/slot signatures, you not only pay for a strcpy() , but also for a doomed-to-fail first lookup attempt. Sure, connects are usually done during startup, and a profiler won’t show you, but using non-normalised signatures is hereby firmly put into the realm of premature pessimisation.

On the positive side, that means we already have the zero-copy fast-path for the case of normalised signatures, and I can strike one more thing from my to-do list 🙂

For all of us, this gives us the following

Guideline: Prefer normalised signal/slot signatures in connect statements.

Luckily, we don’t have to wade through our source code by hand, since the Trolls provide a tool in $QTDIR/util/normalize that you can run on a project to fix the signal/slot signatures up. It doesn’t seem to be shipped in the releases, but you can download it directly from Gitorious: https://qt.gitorious.org/qt/qt/trees/v4.7.3/util/normalize

Note, however, that at the time of writing, it creates sporadic false positives when it hits Q_PRIVATE_SLOT() macros.