[Interest] How to avoid qml engine repeatedly copying and garbage collecting qstringlists?
Ulf Hermann
ulf.hermann at qt.io
Mon Oct 23 15:34:48 CEST 2023
Hi Nikolai,
it would be interesting to see the QML code that produces this behavior.
However, I can very well imagine what's happening there. This is likely
the "value type reference" problem. The list is a "sequence type". It
doesn't have an identity of its own but rather is only accessible as a
copy from your property. However, in JavaScript there is no such thing
as a value (or sequence) type. There are only objects and each object
has a unique identity. Therefore, your list, upon access from
JavaScript, is wrapped into a special JavaScript object so that you can
interact with it. The special object gives you the illusion of a
separate entity by refreshing its copy of the list whenever you read
from it and by writing the copy back to the property whenever you change
it. The illusion breaks down when you retrieve the list a second time,
though. Lacking any actual identity information, the QML engine cannot
find other instances of the same list when accessing it again. Therefore
it has to create a new wrapper object every time.
In contrast to that, for QObject-derived types we have actual identity
information. QObjectPrivate has a field for "declarative data" and there
we store a pointer to the JavaScript wrapper.
There is no simple solution for this. We could probably add some
book-keeping to our QObject wrapper in order to figure out which
properties already have sequence (and value type) wrappers. This is more
complicated than it sounds because value types can have properties of
their own, value types can be stored in lists, and all of this recursively.
If you get qmlcachegen to compile the code to C++ with Qt6, you won't
see the JavaScript wrappers for lists and value types anymore. The
generated C++ code can store the values on the C++ stack instead. But
there are restrictions: In the generated C++ code we can _not_ honor the
object-like nature of value type and sequence references. Anything that
would exploit it won't be compiled to C++. In particular, any function
call and any writing to a property invalidates all value type and
sequence instances currently on the stack. This is because their source
properties may have been changed by code triggered from the function
call or property write.
best regards,
Ulf
More information about the Interest
mailing list