How does QML id property work?
-
How exactly is the id property implemented? Is it like elements with id register inside a quick lookup container? Or is the id resolved in some other way? The id doesn't appear to be a string, so I am wondering how exactly does it work and what is the cost of using it.
-
Hi,
The id is not a property, it is a special attribute stored out-of-band to any other attributes of an object. By which I mean, it's not resolvable via QMetaObject or the QML property caching mechanisms. Instead, the ids are (basically) stored per context, in a vector of idValues (which is basically the QObject to which the id refers the context within which it is valid).
Ids are context-local, which basically means they have "component scope". For more information about them, read http://doc-snapshot.qt-project.org/5.0/qtqml/qtqml-syntax-objectattributes.html#the-id-attribute
As for the cost of using them, it's basically a matter of calculating the hash value of the id string, determining the index into the vector to which the id refers, and pulling out the data from the vector. Resolving symbols is slow, in general, but resolving an id isn't too bad - certainly, it's not like walking up the context scope chain looking for a property resolution, for example.
Cheers,
Chris. -
So the id is resolved during runtime using a hash value as I expected. That would imply the performance penalty for extensive use, long identifiers and lots of them will grow...
Isn't it possible to resolve identifiers and offload at least some of the work, by using a pre-calculated index for the identifiers, specified before execution and only hash those, created during runtime and unknown to the IDE?
-
This is done, with V4 bindings. If it's resolvable at compile time, and the binding is V4able, then the IR generated for the expression involves the lookup by index directly.
However, in general, this can't be done, as the symbol may resolve to something else depending on the current context. As an aside, this is also why every binding in the context gets re-evaluated if a context property is set at runtime.
Cheers,
Chris.