Re: [Development] How qAsConst and qExchange lead to qNN

2022-11-13 Thread Jaroslaw Kobus via Development
> 1. Use overloads for methods that take views or spans. In new API we can
> omit the methods that take owning containers. If the overload set grows
> out of hand, don't add the view/span alternative until we can remove
> something. By Thiago's argument, that means not to convert existing
> methods to QStringView for now.
> 
> 2. Use the postfix "View", "Span" or "Generator" for methods that return
> views, spans or generators rather than owning containers. This way it's
> harder for users to mess up the life time.

Ad 1. Having overloads sometimes causes issues, like e.g. can't be a slot due to
ambiguity when making a signal-slot connection. For this reason I believe that
most (all?) of signals overloads were removed in Qt 6. The similar issues may
be encountered when using QtConcurrent API.

So, if you suggest suffix for Ad 2, maybe make it consistent and use the same 
suffix for Ad 1, too?

Disclaimer: I'm not saying that adding "view" and "span" functionality into Qt 
is a good idea.
It's a bit like giving a raw pointer of some part of your internal data into 
the public API
(however, wrapped nicely with a fashionable envelope - so it shouldn't look so 
bad, right?).
Yeah, in some cases it may save 1 ns for containers having thousands of items. 
But will it make
e.g. rendering QGradient faster (when gradient stops are wrapped with span, as 
Mark suggested)?
Especially, as it was mentioned, typical case is 2, max 3 items?

Qt was always cute, because its API was designed so that it's really hard to 
mess things up.
It looks like we are slowly dropping this beautiful keynote, unfortunately.

Jarek
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] How qAsConst and qExchange lead to qNN

2022-11-13 Thread A . Pönitz
On Fri, Nov 11, 2022 at 09:35:27AM +0100, Ulf Hermann via Development wrote:
> There is an undeniable benefit of _offering_ QSpan, QStringView, and
> generator APIs in a few relevant cases:

This is true, but my problem with this is that already _offering_
additional solutions does not come for free: It bloats the API,
it bloats docs, introducing the first overload is SIC etc.

> 1. Users want to pass a "foreign" container to a Qt function that doesn't
> only store it as QList or QString. It might merely iterate it or store it as
> something else.

Tradionally, we had QList as the (designed to be, and in practice also
being) the "usually good enough for most uses" container, so in a /Qt/
World, this "alien container" case /practically/ had no relevance,

The problem of regularly having to convert between Qt containers has been
/introduced/ by people advocating QList uses by QVector, or std::vector.

> 2. Assume a container that isn't internally stored as QList or QString, but
> is returned from a Qt function. Users want to use that thing as something
> else than QString or QList. For example they might merely iterate it or
> store its contents in a "foreign" container.
>
> In those cases, using QList or QString as transfer mechanism induces an
> unnecessary deep copy.

This is pretty much the same problem: Standardizing on QString and QList
as the "primary" containers avoids these problems on a large scale,
and this overall gain outweighs the effect local micro-optimizations
by far. The problem is that this (un-)balance is hard to communicate,
as it is very easy to demonstrate that small, isolated uses of QString
and QList are suboptimal, but the /overall/ benefit of a uniform
approach only kicks in at "real world"-sized applications.

[Within a function, or a private class, or to access external functions
it's of course fine to use anything that fits and this can be
micro-optimized at will]

> All other cases look much fuzzier to me. QSpan or QStringView (or a
> generator) may be beneficial or detrimental there, depending on exact usage
> pattern.

Right.

> The cost we're avoiding is mostly the reference count, a far cry
> from a deep copy. On the flip side we're introducing complex life time
> problems that will lead to hard to find memory management defects. I suggest
> we look at this from the perspective of a _user_ of Qt. I'm pretty sure you
> can all imagine which problem a user would prefer here.
> So, I suggest we add those "view" APIs to the cases where they provide a
> clear benefit.

Right.

But we should to spell out what "clear benefits" means. I /my/ world it
would not be sufficient to give examples of cases where it helps, but
also need weighing with the expected frequency and against the
(potentially, not necessarily exitsting) costs for other/"normal" users.

> For methods that return a span/view/generator, we should
> always offer a safe alternative that returns an owning container. The naming
> convention should be:
> 
> 1. Use overloads for methods that take views or spans.uIn new API we can
> omit the methods that take owning containers.

I am not sure that in the typical case a span-only is a benefit. As said
before, this leaks implementation details into the API and pessimizes
the case where the user /has/ a container.

> If the overload set grows out
> of hand, don't add the view/span alternative until we can remove something.

I oppose any scheme that makes removal of API a common case or part of
the overall scheme.

> By Thiago's argument, that means not to convert existing methods to
> QStringView for now.

That at least, right.
 
> 2. Use the postfix "View", "Span" or "Generator" for methods that return
> views, spans or generators rather than owning containers. This way it's
> harder for users to mess up the life time.

That's fine.

Andre'
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development