14

I have recently begun using more getter functions as opposed to direct access to make my code more flexible. I am curious what the cost of this is in terms of speed. Suppose that earth is an object and we have the following parent object:

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

Is there a non-negligible difference in speed between the following two statements?

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

2 回答 2

17

在 V8 中:

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

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

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


奖励:在当前 V8 中,这个 jsperf故意使 getter 函数不可内联(通过巨大的注释,这将使函数大小启发式失败)。你可以看到,即使函数没有被内联,它仍然只比直接引用 prop 慢 25%。

请注意,当一个函数不能被内联时,它被认为是一个黑盒,调用函数不知道其副作用,因此速度对代码的上下文高度敏感。

于 2013-09-17T05:29:14.187 回答
3

您不需要在 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

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

于 2017-07-14T07:19:05.633 回答