On 2016-01-16 07:06, Bubke Marco wrote: > On January 16, 2016 06:08:14 Kevin Kofler wrote: >> I suspect we would lose at least some optimizations from >> Q_DECLARE_TYPEINFO. > > std::is_trivially_copyable and other type traits are your friends.
Not really. There is a huge difference between a relocatable type (many, if not most), and a trivially copyable type (a lot fewer). Operations such as growing the buffer can be vastly more expensive if the item type is not relocatable vs. if it is. However, C++ itself currently does not provide any support for relocation. I want to say e.g. std::string is relocatable, but it is certainly not trivially copyable. Now, imagine a std::vector<std::string> where both the vector and strings are very large. When the vector needs to resize, it will have to do a deep copy of ever single item, allocating and freeing lots of memory in the process. Compare to QVector<std::string> (assume Q_DECLARE_TYPEINFO declares std::string relocatable), which... will do a realloc(). Worst case, that's 1 alloc, 1 free, and 1 block copy... and 0 ctor/dtor calls. That's a *significant* difference. (Even using QString instead of std::string does not help much... the QVector still just does a realloc, while std::vector must perform 2*N atomic operations.) ...and then there's QList, which just does a realloc(), *always*. > There are other pitfalls in the qt containers, e.g. > > if (container.contains(key)) > auto value = container.value(key); > > auto iterator = container.find(key); > if (iterator! = container.den()) > auto value = iterator.value(); > > The first looks nice but leads to two lookups. And I have seen it very often. Probably because a) it's easier / clearer to read, b) it's MUCH easier to write, and c) most of the time the performance doesn't matter enough to justify the ugliness of the latter. Specifically, I know I have written code like that *in full knowledge* that it's inefficient, simply because I don't judge it sufficiently inefficient to justify the ugly and obtuse STL syntax. That said, the *correct* fix is: auto value = container.maybe_at(key); if (value) do_something(*value); (...using std::optional or similar) This is easy to read, easy to write, *and* efficient. > I understand the problem. But my problem is more that I have the > atomic pointer which can slow your code done unexpectedly. Compared to what? The pointer only kicks in during a copy or destroy. At the point of the copy, the question is if a deep copy is slower than an atomic operation. At the point of destruction, you are probably slow anyway, though if it's just a dereference, you have potentially saved a heap free. > If you provide data structures which are trivially copy able the > simply could be moved in memory for a vector which is quite fast. ...except not nearly so many data structures are trivially copyable as you would like to think. Many are *relocatable* (a concept that does not yet exist in C++ proper), but *not* trivially copyable. Even move semantics are less efficient than relocation (usually not by much, but still by some). > I don't say that there is no use case for a pointed vector but I can always do > Vector<Entry*> No, you can't. At best, you'd have to do vector<unique_ptr<Entry>>, and you'd still have a leaky abstraction problems. Having the indirection built into the container shields you from this. At best, this seems like an argument that QList should act like QVector for relocatable types up to a certain size (said size being greater than a single pointer, as is currently the case). (I'd be inclined to agree with such an argument, incidentally.) -- Matthew _______________________________________________ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development