[Development] Question about QCoreApplicationData::*_libpaths

Kevin Kofler kevin.kofler at chello.at
Sat Jan 16 01:29:40 CET 2016

Marc Mutz wrote:
> And you will see it over and over again until enough people are fixing
> premature pessimisations in existing Qt code. There's a notable increase
> already. But it takes a long time to turn a supertanker around...

Well, if …

> This is the old difference: you think using std::vector is premature
> optimisation and I think that using QVector is premature pessimisation.

… you think Qt code preferring Qt containers to STL ones is a pessimization, 
then you will always find "pessimizations".

Even if I don't need the CoW in one place, I am still going to pick the Qt 
container for consistency.

> Qt is still a C++ library. If it wasn't for the need for bare-metal speed,
> everyone would use Java instead. It's safer, more coherent, programmer
> productivity is higher and programmer cost is lower.

The thing is, the Qt containers actually make C++ almost as easy to use as 
Java, yet much faster and more powerful. (And even when I find myself 
writing Java code, I miss the CoW semantics. Java's explicit sharing makes 
it easy to shoot yourself in the foot, you have to be careful to clone() in 
the right places, and "constants" are usually not really constant, a final 
object variable still allows writing to the object unless it was immutable 
to begin with. So I find it even EASIER to code in C++ with Qt containers 
than in Java.)

> But safe languages just don't cut it anymore, that's why C++ is still
> alive.

Sure, speed is a big selling point of C++. I just don't see the Qt 
containers ruining it to the point you claim it does.

> But if a seemingly innocuous piece of code like
>    for (const auto &e : qtContainer)
>    funReturningQtContainer().first();
>    ...
> leads to a memory allocations, nay, a complete deep copy of the container,
> then this is simply *not acceptable* in C++. I wouldn't even be acceptable
> *in Java*. It's *orders of magnitude* slower than how an STL container
> would behave. Sure, if this is not a hot code path, you won't notice. But
> these things add up. There's a reason why we can't do much more now with
> the supercomputers that we have on our laps than we could do in the 90s on
> workstations. Compiling Qt, e.g. hasn't gotten any faster between Qt 1.x
> and 5.x...
> But I repeat myself...

There is an easy fix/workaround in both cases: cast the container to a const 
reference, or assign it to a const reference variable. The first case can 
also be avoided by using Qt's foreach instead of the C++11 one.

If you really want to avoid the second pitfall (where first() is really the 
one method this is usually encountered with), then either get a constFirst() 
added to Qt, or (even more effective) convince folks that first() should 
become const by default in Qt 6 and the non-const overload renamed to 
something like firstRef().

Now, what *I* find "simply *not acceptable*" is that "a seemingly innocuous 
piece of code like":
std::vector<Foo> foo1 = …;
std::vector<Foo> foo2 = foo1; // <- here
"leads to a memory allocation, nay, a complete deep copy of the container". 
This is particularly problematic when you want to have methods that return 
an STL container, because returning a reference is a bad idea. (Of course 
you can return a pointer, but that opens its own can of worms, plenty of 
ways to shoot yourself in the foot there: the same issues with explicit 
sharing semantics as in Java, plus memory leaks and more.)

> And why would you advocate learning *two* classes that do exactly the same
> thing if you need the fast one anyway (for when speed matters)? That
> surely isn't good API design.

I never had to port my code from Qt containers to STL containers for speed, 
and it is really the last thing I'd try if everything else fails.

> I don't buy that argument that the STL is less safe. You should teach your
> customers their STL debug mode. They will never look back at the Qt
> containers.

It sure makes it easier to write inefficient code. The cases where STL 
containers deep-copy (simple variable assignment) are much more common than 
the corner cases where Qt containers deep-copy (incorrect use of C++11 for : 
instead of Qt foreach, accidental use of non-const first()).

The class and method names are also a lot less intuitive. And even if you 
abstract the names, the API is less intuitive, e.g., std::queue and 
std::priority_queue have no method like QQueue::dequeue that pops an element 
and returns it, you have to first peek at the front element and then pop it 
(and to add insult to injury, the methods to peek at the front element don't 
even have the same name: std::queue::front vs. std::priority_queue::top, 
which puts us back to the naming issue).

> And no, I cannot believe that using the Qt containers leads to faster
> applications. It may lead to applications faster, but not to faster
> applications.

It does, because otherwise the applications would be written in Java or 
Python instead, surely not in STL C++.

        Kevin Kofler

More information about the Development mailing list