Q_GADGET vs an accessor object for manipulating a polymorphic tree of C++ objects from QML

回眸只為那壹抹淺笑 提交于 2020-01-17 06:14:09

问题


I have a polymorphic tree of C++ types that I need to work with from QML. Memory usage and performance are key here, so I wonder which approach would be more efficient:

  • Q_GADGET - without a doubt the easier and faster way to do it. I can directly use properties (without notifications so no bindings either) and slots to access each object's members. It relies on meta data generation and some kind of object identification in the qtquick runtime.

  • Use an global accessor object for accessing everything, getting or setting object properties, invoking functions and so on. This is definitely the slower and more verbose solution.

I have previously tried with QObject derived types registered as QML types, but memory usage was horrific. I had huge overhead from QObject alone - about 140 bytes overhead for the base 16 byte data set, and instantiating the objects in QML made that even worse, soaring the overhead to around 2000 bytes. Which is unacceptable considering the high object count I am dealing with.

So now I am going the long way, and scrapping the previous design, and wonder what would be the most efficient implementation to take. Also, whether the meta stuff associated with Q_GADGET will work out nicely in a polymorphic scenario.


回答1:


So I decided to give both approaches a test run and make a comparison.

My efforts were cut short, thankfully in their infancy, by the usual obligatory Qt limitation - turns out Q_GADGET doesn't work with pointers, neither properties nor functions are available when working with them on pointer basis.

Only instances are supported for member access, therefore that option is not applicable in a polymorphic scenario. Manual accessor object it is!


Update:

There is a workaround for this, but it involves extra work. Implementing the PIMPL idiom you can have the object instance implementing the properties simply being a pointer to the actual implementation, making all the copying around applicable and efficient.

I ended up not using that approach however, mainly due to the fact it still did not support notifications, and the "3rd party" notification implementation turned out to be too inefficient. Instead I went for a QObject based "proxy" or "accessor" for every object, referenced by a QML element. The proxy is created on demand, and is reference counted, so it only exists whenever an "object -> qml" bridge is needed, which is always only for a very small subset of all objects. The proxy is tightly coupled with the object to avoid penalties of looking it up, while the GUI itself is still abstracted away.

The real world advantage of that implementation compared with the old, QML object based is impressive. From running out of memory on a 32bit build around 300k objects, it is now capable of handling around 500M, a 1666x fold improvement.



来源:https://stackoverflow.com/questions/42843942/q-gadget-vs-an-accessor-object-for-manipulating-a-polymorphic-tree-of-c-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!