I'm working on a performance-intensive library and wanted to see if anyone had some ideas on how to improve the performance of this method which converts our models to a js object.
You'll see below that I've tried to employ a couple of optimization techniques based on my reading:
- Use straight for loops to iterate objects, arrays
- Cache nested objects to avoid excessive lookups (
field = fields[i], etc).
Here's the method I'm trying to further optimize:
toObject: function() {
var i, l, fields, field, schema, obj = {};
for(i = 0, fields = Object.keys(this._schema), l = fields.length; i < l; i++) {
field = fields[i], schema = this._schema[field];
if(!this._data.hasOwnProperty(field) || (schema.hasOwnProperty('output') && !schema[field].output)) {
continue;
}
if(schema.hasOwnProperty('collection')) {
obj[field] = [];
schema.collection.instances.forEach(function (mdl) {
obj[field].push(mdl.toObject());
});
}
obj[field] = schema.hasOwnProperty('processOut') ? schema.processOut.call(this, this._data[field]) : this._data[field];
}
return obj;
}
In particular, I'm wondering if there's a way to optimize:
schema.collection.instances.forEach(function (mdl) {
obj[field].push(mdl.toObject());
});
If I'm not mistaken, the function within the forEach is being created on each iteration. I was going to try and move it out of the main for loop, but then I lose access to field which I need to set the property key on obj.
I also thought about turning this into another for/loop, but then I'd have to create another set of variables like so:
// these vars would be init'd at the top of toObject or
// maybe it makes sense to put them within the parent
// for loop to avoid the additional scope lookup?
var x, xl;
for(x = 0, xl = schema.collection.instances.length; x < xl; x++) {
obj[field].push(schema.collection.instances[x].toObject());
}
This just looks a little ugly, though, to be honest - this is a situation where we are collectively willing to forgo a little readability for performance.
I realize these may be minor micro-optimizations, but they've been shown to add up in my anecdotal experience when modeling several thousands of objects.
forEachyou could usemap.mapis ok.