>>Even our API guidelines stipulate that you should make common things easy and 
>>not-so-common things possible. Sharing is _not_ common and it need not be as 
>> easy as common tasks. I

Maybe for you, but in my works, sharing _is_ common, convenient and safe.
And overal usage of COW is one of the concept that makes Qt stand apart.
>From my POV, COW largely pay off its minimal performance cost.
When performance is a high priority, _an uncommon case_, then using
alternate containers is always possible and we don't need Qt for this.

And when size matters, have this in mind:

sizeof(std::vector<int>) == 32
sizeof(QVector<int>) == 8
sizeof(QList<int>) == 8

 (VC++ 64bit)

Philippe

On Mon, 20 Mar 2017 09:09:57 +0100
Marc Mutz <marc.m...@kdab.com> wrote:

> On Sunday 19 March 2017 19:48:36 Thiago Macieira wrote:
> > On sábado, 18 de março de 2017 15:32:55 PDT Marc Mutz wrote:
> > > On Saturday 18 March 2017 19:30:35 Thiago Macieira wrote:
> > > > QVector<MyType> someFunction()  // out-of-line
> > > > {
> > > > 
> > > >         QtExclusive::QVector<MyType> vector;
> > > >         [ operate and populate vector ]
> > > >         return vector;          // automatic move
> > > > 
> > > > }
> > > > 
> > > > in user code:
> > > >         QtExclusive::QVector<MyType> vector = someFunction();   //
> > > > 
> > > > automatic move [ mutate some more ]
> > > 
> > > Breaks (N)RVO.
> > 
> > How?
> 
> Returned Type != (Declared) Return Type != Expected Type (by caller)
> 
> For NRVO, all three must be identical, for RVO the last two.
> 
> > > And since the code outside has no clue about whether the code inside the
> > > function creates a shared or unshared QVector, the compiler will again
> > > have to emit the whole QVector copy constructor/detach code (as dead
> > > code) at the call site. You promised this would be gone in Qt 6 because
> > > of the removal of the unsharable state.
> > 
> > QtExclusive::QVector's move constructor for QVector always needs to emit
> > copying code, since it doesn't know whether the data is shared or not.
> > There's no way around that.
> >
> > QVector's move constructor for QtExclusive::QVector simply adopts the data
> > and starts reference-counting.
> 
> Sure, I understand that. It's the misuse of QVector when exclusive QVector 
> was 
> needed that is the problem:
> 
> > You could argue that a function that always returns an unshared vector
> > could return QtExclusive::QVector.
> 
> Exactly that.
> 
> > But we should not allow that in our API
> > any more that we allow returning references.
> 
> Yes, that was my fear.
> 
> The exclusive split sounded like a good idea, like unique_ptr vs. shared_ptr, 
> one that could actually win me over to support keeping any form of Qt 
> container at all, long-term. Until right now.
> 
> If you would propose to make QVector exclusive, maybe with SOO, and provide 
> QSharedVector, but to default to QVector in API, you would probably have me 
> on 
> board.
> 
> It's a fallacy to think that there's a lot of need to return a shared 
> collection from APIs. Either you create the collection on request, then an 
> exclusive collection would be preferable, as returning it from a function is 
> free[1], or you "return" internal state, in which case returning some form of 
> view (incl. the case of simply adding begin()/end()) would be the way to go 
> (cf. https://codereview.qt-project.org/150658).
> 
> Even if your pov is that you should always return an owning collection in 
> these cases, and that it therefore has to be a shared one, existing Qt code 
> (QObject::children()) shows that even CoW is too slow in these cases 
> (children() returns by const-&). If QObject was iterable as a container of 
> QObject*, that would both be more convenient as well as faster).
> 
> [1] yes, _is_. Ville may correct me if I'm wrong, but afaiu, C++17 makes
>  (N)RVO mandatory. Sorry, GCC, you'll have to finally do something about your
>  broken NRVO.
> 
> > > > Why not std::vector? Because of the ability to put it back into shared
> > > > mode,
> > > 
> > > std::shared_ptr<const std::vector>
> > 
> > One level of indirection too many. We've been over this.
> 
> iow: you'd rather pay some large overhead every time than pay a larger one 
> only in cases where it's needed. And this is where we fundamentally disagree.
> 
> Even our API guidelines stipulate that you should make common things easy and 
> not-so-common things possible. Sharing is _not_ common and it need not be as 
> easy as common tasks. Iteration, builing a container from scratch, returning 
> by NRVO from a function, these are common things. And CoW pessimises such 
> common things - not only performance-wise, but also conceptually: std::vector 
> doesn't need qAsConst when used with ranged for loops, std::vector doesn't 
> invalidate iterators when copied from...
> 
> Thanks,
> Marc
> 
> -- 
> Marc Mutz <marc.m...@kdab.com> | Senior Software Engineer
> KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
> Tel: +49-30-521325470
> KDAB - The Qt, C++ and OpenGL Experts
> _______________________________________________
> Development mailing list
> Development@qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development


_______________________________________________
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development

Reply via email to