Registering Singleton vs Context Property
-
Hey hey
I have to pass settings from C++ code to QML , so I have two ways to go either using context
@
QtQuick2ApplicationViewer viewer;
WindowSettings windowSettings;
viewer.rootContext()->setContextProperty(QStringLiteral("settings"), &windowSettings);
@or like this
@
qmlRegisterSingletonType<WindowSettings>(SETTINGS_URI, 1, 0, "Settings", settingsPovider);
@Just curious, what is the better approach?
-
I vaguely recall that the Singleton type is better optimised in the engine, and currently it is recommended to use that. You would need to check with QtQml/Quick developers to be sure, though.
-
The type information for singleton types is registered with the QML engine, and cannot change dynamically at runtime, and hence expressions involving the singleton type can be optimised far more easily than they can for a context property (which will be a generic QObject* type, internally).
Think of a binding which includes someContextProperty.something.
Since the "someContextProperty" can be changed dynamically, its type can be different between two evaluations of the binding, and so the "something" access can resolve differently in each evaluation (the first time, it may be an integer property; the second time, it may be a string property, for example).So, the code which is generated for the binding which involves a property access on a context property is going to be far less optimal than the code which is generated for the singleton access.
For more information, see http://qt-project.org/doc/qt-5.0/qtquick/qtquick-performance.html#bindings
Note that the updated V4 engine in Qt >= 5.2 will have some impact on the types of the expressions which can be optimised (due to the fact that more type information can be introspected at runtime by the JS engine due to closer integration with the QML engine) but I don't know whether context property lookups is something which has been improved dramatically, yet.
(Theoretically, whenever the type of the context property changes, you could regenerate the compiled bindings which capture that resolution, so that the compiled bindings are always the most-optimal-form for the current runtime state of the application. But, doing so is expensive, and if the binding is rarely evaluated, then you're doing that recompilation for no reason. Using a JIT would partially solve that problem, but then you are explicitly using a less-optimal form of the binding to begin with. So, the short answer is: using the most-strongly-typed form in bindings is always going to be the most optimal at runtime.)
Cheers,
Chris. -
Thank you very much for your answers, gentlemen.