[Development] How qAsConst and qExchange lead to qNN

Philippe philwave at gmail.com
Tue Nov 15 12:50:43 CET 2022


On Tue, 15 Nov 2022 08:52:24 +0000
Marc Mutz via Development <development at qt-project.org> wrote:

> There's nothing inherently Qt-ish about owning containers.

Yes and no, because owning containers are part of the very "Qt-ish"
Implicit Sharing idiom, which one is _great_ for the ease of use, safety
and optimization it provides.

~115 Qt classes: https://doc.qt.io/qt-6/implicit-sharing.html

>QAnyStringView, QUtf8StringView and, later, QAnyString, QUtf8String,
> can be used to to make UTF-8 a first-class citizen in Qt.

Maybe, but I see a deviation from simplicity (not "Qt-ish")

>But UTF-16 is sacrosanct in Qt. It's a cult. Irregardless of how many 
>deep copies it takes to convert to and from UTF-16 from native 
>encodings, people still worship it as god-given. It's not.

If this is "sacrosanct", this is simply because many people appreciate
QString for its rich API and ease of use. This has to be respected.

Philippe

> On 15.11.22 08:14, Ulf Hermann via Development wrote:
> >>> So, if the method immediately converts whatever it gets to QList or
> >>> QString, then there is no point in passing it a span or view.
> >>
> >> My point is that there _is_. Citing my blog post:
> >>
> >>     callConsumeQStringHelloWorld():
> >  > [...]
> > 
> > That's the worst case scenario of passing an 8bit string literal to a 
> > function that takes a QString. We have QStringLiteral to avoid the 8bit 
> > to 16bit conversion, but I know there are more problems with that.
> > 
> > Now lets look at the case of passing a pre-existing QString (i.e. one we 
> > don't have to create in place) to a function taking QAnyStringView and 
> > storing the result as QString.
> > 
> >      // somewhere:
> >      QString a;
> >      void setter(QAnyStringView view) { a = view.toString(); }
> > 
> >      // elsewhere:
> >      QString foo;
> >      [ ... modify foo ... ]
> >      setter(QAnyStringView(foo));
> > 
> > That's a deep copy. A deep copy of a string is obviously more expensive 
> > than the overhead of calling the QString ctor and dtor.
> 
> That remains to be proven. A rule of thumb for atomics is that they're 
> two orders of magnitude slower than a normal int. They also still act as 
> optimizer firewalls. With that rule of thumb, copying 50 char16_t's is 
> faster than one ref-count update. What really is the deciding point is 
> whether or not there's a memory allocation involved. I mentioned that 
> for many use-cases, therefore, a non-CoW SBO container is preferable over a CoW 
> non-SBO one.
> 
> If QString and QByteArray had both efficient substringing and SBO, my 
> arguments would carry much less weight. But we have neither, and adding 
> it (esp. SBO) to QString for Qt 7 will break users, silently. Therefore 
> it's prudent _not_ to change QString, but to add QSmallString or 
> something instead. Until then, u16string and QVLA<char16_t> can be used, 
> by users and implementations.
> 
> Any way you turn it, non-owning containers in the API make for long-term 
> stable APIs even as we improve our container classes in incompatible ways.
> 
> > Which case is 
> > more common? And by what factor?
>  >
> > I can't say what case is more common. What I can say is that the risk of 
> > creating deep copies sounds worse to me than the risk of calling the 
> > QString ctor and dtor too often.
> >
> > This is what I mean with "fuzzy". We don't really have the data to 
> > support a move to QAnyStringView for all of our API.
> 
> I can say with firm belief that, _atm_, passing QString is more common. 
> But this is a self-fulfilling fact. The tst_qsettings experiment shows 
> what can happen if you port an API that doesn't naturally receive 
> pre-made QStrings.
> 
> If you want to take a peek at a world without owning containers, use the 
> Qt 6 QXmlStreamParser API or llvm.
> 
> With the caveat that the problem with QXmlStreamParser is that it needs 
> to convert to UTF-16. The vast majority of XML data is _not_ in UTF-16. 
> If QXmlStreamReader's API was formulated in QAnyStringView, it wouldn't 
> have to. We could just mmap() files and hand out QAnyStringViews to 
> tokens. Not going into whattaboutism here, but what about all those 
> unnecessary encoding conversions? Each one is a deep copy, too. UTF-16 
> is a total alien in the Unix world, and, connecting to your world, I 
> think it's safe to assume that very few QML files are encoded in UTF-16, 
> either. And PySide string are also not encoded in UTF-16, I think.
> 
> But UTF-16 is sacrosanct in Qt. It's a cult. Irregardless of how many 
> deep copies it takes to convert to and from UTF-16 from native 
> encodings, people still worship it as god-given. It's not.
> 
> No-one would use Clang if it internally converted everything to UTF-16 
> first. It would be too slow.
> 
> QAnyStringView, QUtf8StringView and, later, QAnyString, QUtf8String, can 
> be used to to make UTF-8 a first-class citizen in Qt.
> 
> Likewise, owning containers are also sacrosanct in Qt. They're a cult. 
> Irregardless of how many deep copies it takes just to call a Qt function 
> from Python, Java/Script or QML, people still 
> worship them as god-given. They're not.
> 
> There's nothing inherently Qt-ish about owning containers. Qt is all 
> about allowing developers to write great applications across platforms. 
> Ideally, we'd focus on picking up developers where they come from. That 
> means instead of inflicting a Java-ish C++ API on Python programmers, we 
> make PySide rock by minimizing copies between Python and Qt/C++ data 
> structures. iow: NOI.
> 
> Guys, take the blinkers off :)
> 
> Thanks,
> Marc
> 
> -- 
> Marc Mutz <marc.mutz at qt.io>
> Principal Software Engineer
> 
> The Qt Company
> Erich-Thilo-Str. 10 12489
> Berlin, Germany
> www.qt.io
> 
> Geschäftsführer: Mika Pälsi, Juha Varelius, Jouni Lintunen
> Sitz der Gesellschaft: Berlin,
> Registergericht: Amtsgericht Charlottenburg,
> HRB 144331 B
> 
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> https://lists.qt-project.org/listinfo/development




More information about the Development mailing list