[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