View Single Post
Old 07-23-10, 10:42 AM   #32
Registered User
Join Date: Jan 2005
Posts: 19
Default Re: is the nvidia driver falling behind?

You are encouraged to pass objects by const reference, nobody prevents your from doing this. But even if you pass the object by value, you save cpu and memory, because the container does the copy on write.
You ARE NOT encouraged to pass container objects by const reference. Give you a hint, find a public API function in Qt that accepts a constant reference to a Qt container class, same goes for QImage and QPixmap and many others.

There is a big horrible stinking issue with this copy on write business:
1) I cannot tell from a function declaration if a copy does happen, this is horrifyingly bad. I cannot tell from a function declaration at all. Care about performance you care about this a great deal.
2) If I fetch a read only pointer from a Qt container class, save that, and then modify the contents of the Qt container the pointer is not correct. At first such a use case seems artificial but it rears it's ugly head a great deal. This is an issue when using GL, and the Qt GL code has this. QImage using in Qt source looks even funkier, but it is the way it is because of this pass by value-copy-on-write business of Qt. Qt's API is almost all pass by value where as pass by constant reference is the way it should have been.

I would not mind Qt's containter class if the Qt API would accept STL containers, but it does not, at all. Thus to use the Qt API you need to use Qt's container classes which are pretty poor. That Qt started before STL and RTTI(for moc) before they were reliable is a historical reason. That does not change the fact that they are inferior. Worse, STL and RTTI have been reliable for atleast, what, 8 years atleast, plenty of time to replace the Qt container classes with STL ones.

Javascript) Is GTK's Javascript engine faster? Oh wait, there is none.
Exactly, you can choose your javascript. In Qt you MUST use Qt Javascript which is nowadays one of the worse Javascripts around. Sadly, one of Qt's most promising components QML must use Qt Javascript and that will hurt QML's performance, particularly in embedded devices where much of the action is nowadays. Oh wait. Qt's drawing sucks too. The lack of modularity inside of Qt makes it impossible to replace a poor component with a better one.

- e.g. KDevelop provides static analysis to spot connect() errors
Wonderful, to pick up an error that the compiler should pick up I have to use a particular IDE. No dice.

Re: MOC) moc provides way more features than RTTI.
List the features is provides, please do. While listing them think about what it is and how there are better ways to do each of them. At the very least, list them, and I will then tell you.

I suppose you might be referring to this from Qt: among other bits.

Let me diagnose the failures here, ok.

Firstly adding member functions, or for that matter virtual member functions does not increase the size of an instance of a object in C++ once that object already has virtual member functions.

There are other amazing lines such as this beauty:
"And we can have overloaded signals and slots, which feels natural when programming in a language where overloads are a key concept. "
Priceless. sigc++, boost signals all handle overloaded function calls.

Other bits:
Another benefit is that we can explore an object's signals and slots at runtime. We can establish connections using type-safe call-by-name, without having to know the exact types of the objects we are connecting.
The line of not knowing the exact types, is rich. Can anyone say "base class and virtual methods" Now you can make a case: get function name by string name. This lets you not have the header file to the classes you are connecting. You can also make the case that being able to list the slots and signals of a class at run time and then conneting them. Alas, there are better ways to do this than Qt's system. Much better ways.

The richest sections of that is "Calling Performance is Not Everything". Plenty of signal libraries (such as sigc++ and boost:signal2 do marshalling and all that Qt's object system provides WITHOUT requiring a tool to execute on C++ source code to produce more C++ source code). Oh and runs more efficiently.

Another point is that if you had deleted an object at the other side of a connection, you don't have to worry about a crash from calling a function on a freed object. Epic fail. They have traded a crash for a host of harder to track down object. "I did connect that signal to foo's which connect bar's slot, why is not bar's slot getting called? Oh someone, somewhere deleted foo" The big failure here is that Qt has essentially a broken quasi-garbage collector. It sort of deletes children of objects correctly and calls disconnect for you, but it introduces a great deal of unpleasant surprises.

As they talk about their qdymamic_cast<>, it starts to look even worse.

One point that they totally missed: they added moc to get around C++ deficiencies of over 10 years ago. The need for moc has not existed since g++ 3.x. Another very creepy part: the attitude of trying to provide lots of programming safety in C++, they don't like iterators and more. They miss the point: if you want lots of safety choose a "managed language" such as Java, or many others. The safety provided by Qt is only skin deep and trades crashes for more subtle and harder to diagnose bugs.

One amazing point of honesty that made was that objective C is great, and get this people: Objective C code doing what Qt's signal/slot code does is about 5-10 times more efficient and more flexible. Sighs.

You ranted a lot about Qt, but didn't give a single argument in favor of GTK/GDK. Even more, for some of those "issues", there is not even an equivalent in GTK.
Lets first address a serious issue with Qt, that I stated before: it does many things, but many of those it does very poorly, I would be kind in saying it is a jack of many trades and master of none. Now onto GTK/GDK:
1) Notice GTK and GDK: there is a separate library for separate purposes, moreover GTK/GDK has additional widget libraries with specific purposes. Qt does not. Along the same lines GTK/GDK leverages libraries that are for very specific purposes. In contrast, Qt mostly does not or attempts to completely hide such.

2) With GTK/GDK there is a C interface and a C++ interface through gtkmm, etc. Qt is C++ only AND it is a deviant form of C++ at that.

3) QWidgets and QGraphicsWidgets have many, many flags; in contrast GTK/GDK do not. This is a good thing. Many of the flags for QWidgets and QGraphicsWidgets are poorly documented and their interactions as well. As such, to really see what is going on one has to open up Qt source code. GTK/GDK widgets have no way near as many flags or surprises in using them.

One point that you are completely missing, which to some degree is one of the big points of Unix: make a simple tool or library that does one "thing" and does it well. Qt does many things, and none of them very well. For each component of Qt there are much better alternatives. GTK/GDK gives more options, and oh yes, performs better.

There are so many better tools and ways to accomplish what Qt attempts to do, these ways being faster, more stable, fewer surprises and *ahem* better documented than reading Qt source code.

I would like to see Qt fixed, particularly the drawing stack. However, it is not a matter of fixing so much as re-doing. The Qt containers should be dumped. The internals of Qt need a horrible cleaning up to be better modularized. Qt as a whole needs to be better modularized so that poor performing components can be removed and replaced with better, already existing solutions. Qt layer to such is fine and acceptable. However pretending that Qt is just fine is not acceptable. Put Qt on an embedded device and watch the poor thing crawl. Embedded devices are where the action and future of open source consumer goods are located.
kRogue is offline   Reply With Quote