Closed gotjoshua closed 4 years ago
I think simply caching o[key] in a const before this code block at L#278 could at least help a bit:
if (o[key] && has(o, key) && !isPlainObject(defPart) && !isModelInstance(o[key])) {
o[key] = cast(o[key], defPart) // cast nested models
}
if (isFunction(o[key]) && key !== "constructor" && !privateAccess) {
return grantPrivateAccess(o[key])
}
if (isPlainObject(defPart) && !o[key]) {
o[key] = {} // null-safe traversal
}
That seems totally right. Thanks for the investigation, will try to push a new version today
Fixed in v4.0.6
Is there a tag for that?
Added a git tag.
I made another pen that does 1000 instantiations and 1000 calls to a getter that also uses another getter. The difference is noticeable between 4.0.6 and 4.0.5!
However, the performance compared to normal objects is still a bit disturbing:
So, we used to use ObjectModel for both our data objects (OMs) and ViewModels (VMs) The VM was a very simple ObjectModel that only needed to check that it's _om prop was an instance of the correct OM. Then the VM is extended (as the model is not "sealed") with many getters that do not need to be validated. Today we discovered that the getters are called 3 times internally to ObjectModels get function. We promptly transformed our BaseVM into a normal object and see noticeable differences across all UI interaction.
I made a code pen to illustrate: https://codepen.io/gotjoshua/pen/qBdmJQP
I know that using ObjectModel comes at a cost, but 3x on all calls to getters that don't need validation at all seems excessive.