Optimizing data model updates
The data binding feature of our plugin allows users to easily expose C++ data to the JavaScript end and keep it synchronized through the use of data models. While sharing data to the UI can be done without much effort, users can easily expose the data in an unoptimized way that can have a negative impact on the overall performance.
An example is if users expose their data using a single data model. In most situations, such a data structure would include properties that rarely change and ones that are modified every frame. Let's refer to these as “static” and “dynamic” data respectively.
The current state of the data binding feature allows us to update data models as a whole and not per property. This means that whenever we update only one property of a data model, we have to mark the whole model for updating and synchronization. Internally, our plugin will update all properties and re-evaluate the data-binding attributes.
In an actual use case, such a situation can cause many redundant re-evaluations of data binding properties, resulting in negatively impacting performance. For example, let's take a look at the scenarios below:
- We have an event that updates a static data set that changes every now and then(e.g., not frequently) and modifies one variable. Such a small change will cause the whole GameState data model to be updated and all data binding properties re-evaluated.

- We have an event that updates a dynamic set of game data that can have many variables and must be updated for every frame. Here the cost of updating the data model will be slightly higher than the example above as we take slightly more time in C++ to update all Mini Map data.

Now let's have a look at how these two scenarios will perform based on how we’ve set up our data models:
One data model setup - In the following example, we have a single member that is our Game State and holds all of the static and dynamic data.

Considering that data models will be updated and synchronized as a whole - whenever we update a single property in the static data set the performance cost is ~0.41ms. This is significantly high for such a small change.

And when we update the dynamic data that modifies the properties of many objects, the cost is slightly higher(0.62ms) due to the additional C++ logic required to update the position data of the mini-map elements.

Split data model setup - with this approach of splitting data into different models based on the update frequency, we effectively reduce the number of data model properties and data-bind attributes that have to be processed. In the example below we have a similar setup as the single data model, but instead, we have the Mini Map(holding our dynamic data) as a separate data model.

When making a change to many properties of the dynamic data, the cost is ~0.60ms. It is identical to the performance of one data model setup as the static data variables themselves in the example are not that many.
Finally, when making a change to one property of the “static” data, the cost is ~0.15ms, which is significantly lower as the single property change will only update the static model data and not the dynamic data.

Considering these results, it is a good practice to keep data models separated based on the frequency they are updated. We plan to introduce partial data model updating, allowing users to update and synchronize a single property. You can keep an eye on our changelog(click) to find out when such changes roll out.
If you want to experiment with the test case used for this, you can download the package from here(click) and extract it into the SampleHelloCohtml_WinDesktop project that we ship with the native package of our plugin. To switch between one or two data-model setups, you can use the definitions at the top of the SampleHelloCohtml.cpp file.
-
Looking forward to the partial data model updating!
1
Please sign in to leave a comment.
Comments
1 comment