循环在性能测量中产生了巨大的差异

Loop making a huge difference in performance measurement

本文关键字:巨大 产生了 性能测量 循环      更新时间:2023-09-26

我正在尝试创建可池对象,或者换句话说,是回收的对象,而不是从头开始创建新对象,这太慢了。

var Poolable = {
  pool: [],
  new: function(args) {
    var obj;
    if (this.pool.length > 0) {
      obj = this.pool.shift();
      obj._recycled = false;
    } else {
      obj = Object.create(this.prototype);
    }
    this.apply(obj, arguments);
    return obj;
  },
  delete: function(obj) {
    if (obj._recycled) {
      throw ("This object has already been recycled!");
    }
    obj._recycled = true;
    this.pool.push(obj);
  }
};
var extend = function(a, b) {
  for (var i in b) {
    if (b[i]) {
      a[i] = b[i];
    }
  }
  return a;
};
var Vector = extend(function(x, y) {
  this.x = x;
  this.y = y;
}, Poolable);
Vector.prototype.add = function(v) {
  this.x += v.x;
  this.y += v.y;
};

我可以这样使用:

var v = Vector.new(1, 2);
// When I'm done
Vector.delete(v);

我对此进行了测试,看看是否有任何明显的改进,但后来发生了一件奇怪的事情:在大for循环中使用Poolable版本要快得多,而在小for循环中不使用Poolable的版本要快的多。

小循环:http://jsperf.com/poolable-vs-non-poolable-objects/8

大循环:http://jsperf.com/poolable-vs-non-poolable-objects/9

问题:我在哪里把考试搞砸了?

对于这两个测试,我得到的可池基准测试都比非池基准测试慢。。。我是不是错过了什么?

在非池测试中,你没有删除对象,所以当测试完成时,它们可能会被删除,这会带来更好的性能。此外,我认为可池版本引入的额外逻辑对小循环有性能成本,但开始比大数据集上的非池更高效,这可能就是你想要的?

对于这样一个简单的结构,您是否尝试将整个Object.create+extend替换为:

obj = { x: x, y: y }