[Development] How qAsConst and qExchange lead to qNN

Marc Mutz marc.mutz at qt.io
Wed Nov 16 19:11:53 CET 2022

Hi Volker,

On 14.11.22 19:00, Volker Hilsheimer wrote:
> Today, the vast majority of client code already has an owning container that gets passed around by copy or as const references.

There are important subsets that don't, e.g. the aforementioned 
serialisation APIs and where 10%+ executable code savings can be had:

- https://codereview.qt-project.org/c/qt/qtbase/+/353688
- https://codereview.qt-project.org/c/qt/qt3d/+/263444
- https://codereview.qt-project.org/c/qt/qt3d/+/157737

> In Qt, we usually store data in the implementation in QList and QString. A test case that artificially creates a ton of QString instances perhaps rather falls into the small and isolated use case that doesn’t translate very well into real applications.

I disagree that tst_qsettings isn't a real-world application. Most Qt 
applications will have a part that does serialisation into one of JSON, 
QSettings, or XML, and checking the impact of QString -> QAnyStringView 
on a test that does makes perfect sense to me to gauge the impact on 
that part of the API. Granted, it's a maximum-attainable savings gauge. 
But it's one of the better indications we have, apart from looking at 
the assembly generated, on how QAnyStringView affects codegen.

That said, there are also Qt apps that don't use tr() and just pass 
string literals for human-readable text. Those would get a similar 
reduction in executable code size if _all_ QString setters were replaced 
by QAnyStringView ones.

The file APIs also suffer from the forced use of UTF-16 for paths (cf. 
https://bugreports.qt.io/browse/QTBUG-104095). Hands up: who has in the 
past been lazy and said "meh, QFile::encodeName(), I'll just skip that" 🖐

> There are most certainly classes where it’d be good if we could replace that implementation with e.g. a std::pmr::vector with an optimised allocator. And then being stuck with a QList API forces both us and client code to construct suboptimal data structures. And there are APIs where replacing the QString version with QAnyStringView makes perfect sense (such as all remaining fromString factory functions).
> But that we either replace all, or none of our APIs with something taking a view or a span are perhaps not the only outcomes of this conversation.

https://bugreports.qt.io/browse/QTBUG-101388 explicitly proposes to 
start where there's the most bang for the buck, and I've been following 
it to the letter.

> Can we focus on the cases with the biggest wins, like you already did with QRegion, QSettings, and QObject::setObjectName? What APIs in Qt that take a QString are usually called with a string literal in real applications, rather than with an already created QString object (that is in turn the result of user input or reading from some storage)?

Exactly what https://bugreports.qt.io/browse/QTBUG-101388 proposes.

> What was the outcome of the QObject::setObjectName change for e.g. Qt Creator?

I don't have numbers for QtC, but I have numbers for uic-generated code:


That's not separated from the rest of the code, so I take it fits the 
real-world benchmark better: In particular those 1.7% are _just_ 
setObjectName(). Just in uic-generated code. 1.7% of executable code 
previously wasted on temporary QString creation in a real-life library. 

And the simplest code is also the most efficient:


The sad fact is that this is just rolling back the inefficiencies caused 
by making objectName a QString in Qt 4.

> What would a QSpan-returning implementation of e.g. QObject::findChildren or QItemSelectionModel::selectedIndexes look like? Is that even feasible without using coroutines?

It's not possible. As per my previous emails, a span can only be used to 
return stored contiguous data. Returning computed or non-contiguous data 
requires a co-routine (or callbacks) (NOIv1 vs NOIv2).


Marc Mutz <marc.mutz at qt.io>
Principal Software Engineer

The Qt Company
Erich-Thilo-Str. 10 12489
Berlin, Germany

Geschäftsführer: Mika Pälsi, Juha Varelius, Jouni Lintunen
Sitz der Gesellschaft: Berlin,
Registergericht: Amtsgericht Charlottenburg,
HRB 144331 B

More information about the Development mailing list