QML profiling: creation takes a long time
-
I have profiled my application using QtCreator QML profiler. I see that compiling and binding my QML files is fast. I also see that the bytecode CREATING (qml profiler) takes a long time ( 2 seconds ).
What does the CREATING step means? I read somewhere that this is the creation of c++ objects by the QML engine. I cannot zoom in the CREATING step so I cannot see exactly what is taking so long..
-
Anybody has an idea what could take so long?
-
I see two reasons here: either there is a bug in QQmlVME which results in an unreasonably long execution time or your QML is overly complex which results in the same behaviour given your hardware constraints.
However, the advice stays the same. Create a suitable example, at least including an affected QML file, the created bytecode (set QML_COMPILER_DUMP=1) and your hardware contraints, and forward your problem to development@qt-project.org.
-
Hi,
Instantiating the hierarchy of QObjects will always be a long and arduous task, simply because QObject itself is very inefficient (including all of the signal/slot connection stuff). In QtQuick1/QML1, a QObject-derived class was used as the basis for all binding expressions, which is expensive for obvious reasons. In QtQuick2, this was alleviated to a great extent with specialised binding and expression classes, but first-time binding instantiation and evaluation will always be expensive (and happens after the rest of the QObject hierarchy is instantiated, for obvious referencing reasons).
Another thing to look into is whether a large part of the time is taken up in Exception generation and handling. Since the binding evaluation order isn't specified by the language (it is specified implicitly by the implementation of the language, but that doesn't help developers ;-) it can happen that "transient" errors occur during lookup, which can be hideously slow.
eg:
@
Item {
property Item someItem: someComponent.createObject(); // etc
property int randomX: someItem.x
}
@the binding to randomX can cause a "transient exception" if the bindings are evaluated in the wrong order (1 - randomX evaluated, exception since someItem is null, and therefore null.x is an exception; 2 - someItem evaluated, triggering re-evaluation of randomX; 3 - randomX evaluated, succeeds).
While in QtQuick2 some code was added to try to minimise the likelihood of this occurring, these sort of situations are still possible (and presumably happened regularly with QtQuick2).
So, you can try twiddling the order in which property declarations or property initialization statements are made in your QML files, to see if that results in a different binding evaluation order. In most cases, I would say that the effect would be unnoticeable, but it's worth being aware of.
Cheers,
Chris. -
Correct, I also noticed that if you use javascript expression like below the creation time is also increased significantly:
@
Item {
height: getHeight()function getHeight()
{
if (expression==true)
{
return whatever
}
else
{
return somethingelse
}
}
}
@Also Listviews and delegates is awfully slow:
@
Listview {
model: myModel
delegate : Text { text : "test" }
}
@Also if I use Loaders and Binding todynamicly load components the Loaders and Binding themselves take quite some time to compile and create. For example creating 20 loaders and 100 bindings take 5 or 6 seconds!
-
Just to clarify, are you using QtQuick1 or QtQuick2?
ISTR Michael Brasser did some work with the Binding element in QtQuick2 to make it faster, but yes in general, because it's entirely dynamic (ie, everything is resolved at runtime rather than at compile time, because you can assign to the Binding element's "target" property) nothing can be optimized at the bindings level. Loaders shouldn't be too much slower than any other elements, except that if they are active by default, you may be doing work sooner than you except (I'm probably wrong about the default settings there, though - my memory is rather hazy).
ListView and delegates should definitely not be slow.
If you can nail down exactly what is causing the cost there, we need to know.
Is it in getting the data from the model to instantiate each delegate? Or is it the instantiation of each delegate (remember, each one is a separate object, so if you have a complex layout in the delegate that will, naturally, take a long time) what is taking so long?Cheers,
Chris.