Javascript 为什么更长的继承链在我的jsperf TST中花费的时间更长

Javascript 为什么更长的继承链在我的jsperf TST中花费的时间更长,javascript,performance,prototype,performance-testing,Javascript,Performance,Prototype,Performance Testing,我试图了解长继承链的性能成本,因此我设置了一个jsperf测试: 以下是设置代码: Person = function (name) {this.name = name} Person.prototype.title = function () { return this.name } kinds = {"-1": Person}; instances = {"-1": new Person("john")} for (var i = 0; i < 10; i++) { kinds[

我试图了解长继承链的性能成本,因此我设置了一个jsperf测试:

以下是设置代码:

Person = function (name) {this.name = name}
Person.prototype.title = function () {
return this.name
}
kinds = {"-1": Person};
instances = {"-1": new Person("john")}
for (var i = 0; i < 10; i++) {
  kinds[i] = function (name) {this.name = name};
  kinds[i].prototype = new kinds[i-1];
  kinds[i].prototype[i] = function () {
    return this.name
  }
  instances[i + ''] = new kinds[i]("john")
}
test = function (i) {
  instances[i].title();
}


然而,第一次测试的时间要长一个数量级。我很确定第一个测试应该更快,因为它不必遍历继承链。

答案很简单,在
test
函数中访问
instance[I]
比访问
title()
需要更长的时间

为了修复测试,我用两个变量替换了测试函数:

instanceOne = instances["-1"]
instanceFive = instances["5"]
这两个测试用例很简单:

instanceOne.title()

结果如您所料:

无继承链-762760656-最快
5个双亲-717293580-慢6%

除了现在它没有进行太多真正的测量-当它达到基准时,优化编译器会完全删除基准循环中的所有内容(70000000中的数字通常意味着“基准空循环”),差异来自优化之前的差异-1只是一个非常不幸的选择——直到最近,V8还没有将它与其他命名字段同等对待——这意味着访问它的速度非常慢。现在也修好了。谢谢你的解释,我得写一个更复杂的测试。很高兴知道编译器正在进行大量优化。
instanceOne = instances["-1"]
instanceFive = instances["5"]
instanceOne.title()
instanceFive.title()