吸气功能与直接接入的速度

时间:2013-09-16 22:42:47

标签: javascript performance getter

我最近开始使用更多的getter函数,而不是直接访问,以使我的代码更灵活。我很好奇这个成本在速度方面是多少。假设earth是一个对象,我们有以下父对象:

var star={}
star.planet=earth
star.getPlanet=function(){
  return this.planet
}

以下两个陈述之间的速度差异是否存在不可忽略的差异?

print(star.planet)
print(star.getPlanet()) 

2 个答案:

答案 0 :(得分:13)

在V8中:

如此简短并且没有上下文分配变量的函数将被内联。除非当然已经累积了过多的内联,在这种情况下,调用仍然非常便宜,因为函数的整个执行部分适合64字节指令高速缓存行。

当您的函数使用例如arguments而不是处于严格模式或定义引用函数变量的内部函数时,会发生上下文分配的变量。另一个问题是,如果调用者和被调用者不能共享相同的上下文,则无法内联x64函数,总而言之,避免像瘟疫那样的闭包。

请参阅:http://jsperf.com/312319sakd虽然看起来firefox使用死代码消除(这是令人沮丧的,因为浪费时间这样做?)。


Bonus:this jsperf故意让getter函数在当前的V8中不可嵌入(通过巨大的注释,这会使函数大小的启发式失败)。你可以看到,即使函数没有内联,它仍然只比直接引用道具慢25%。

请注意,当函数无法内联时,它被认为是一个黑盒子,其副作用对于调用函数是未知的,因此速度对代码具有高度上下文敏感性。

答案 1 :(得分:2)

您不需要在JavaScript中创建这样的冗余getter / setter函数。如果您在稍后阶段需要在设置属性时进行一些验证,或者在获取属性时需要进行一些准备,则可以执行此操作。

var star = {
    get planet() {
        this._planet.prepare()
        return this._planet
    },
    set planet(planet) {
        if (! isPlanet(planet))
            throw Error('Not a planet')
        this._planet = planet
    }
}

star.planet = earth

...而不是改变对象的用法。