优化嵌套For循环

时间:2014-06-04 22:04:23

标签: javascript node.js optimization

我正在开发一个性能密集型库,想知道是否有人对如何提高将我们的模型转换为js对象的方法的性能有一些想法。

您将在下面看到我尝试根据我的阅读使用一些优化技术:

  • 使用直接循环来迭代对象,数组
  • 缓存嵌套对象以避免过多的查找(field = fields[i]等)。

以下是我正在尝试进一步优化的方法:

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;
}

特别是,我想知道是否有一种优化方法:

schema.collection.instances.forEach(function (mdl) {
  obj[field].push(mdl.toObject());
});

如果我没弄错的话,每次迭代都会创建forEach中的函数。我打算尝试将其移出main for循环,但后来我无法访问field,我需要在obj上设置属性键。

我还考虑过将其转换为/ loop的另一个,但是我必须创建另一组变量,如下所示:

// 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());
}

但是,这看起来有点难看,说实话 - 这是我们集体愿意放弃可读性的情况。

我意识到这些可能是次要的微观优化,但在建模数千个对象时,它们已被证明可以加入我的轶事体验。

1 个答案:

答案 0 :(得分:1)

你建议的for循环和你一样好。您可以采取的一些优化措施是避免属性查找:

var objval = obj[field],
    instances = schema.collection.instances;
for(x = 0, xl = instances.length; x < xl; ++x) {
  objval.push(instances[x].toObject());
}

在半相关的说明中,hasOwnProperty()确实会导致显着的性能损失(与field !== undefined之类的更简单的事物相比)。