Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

speed of getter function vs direct access

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()) 
like image 356
gloo Avatar asked Sep 16 '13 22:09

gloo


People also ask

Are getters and setters slow?

Getters and setters are essentially sugar-coated wrappers for methods. So it's going to be slower than directly accessing something. Moreover, things are getting weird with structs.

What's the advantage of using getters and setters?

The getter and setter method gives you centralized control of how a certain field is initialized and provided to the client, which makes it much easier to verify and debug. To see which thread is accessing and what values are going out, you can easily place breakpoints or a print statement.

What is the difference between a getter and a setter?

Getters and setters are used to protect your data, particularly when creating classes. For each instance variable, a getter method returns its value while a setter method sets or updates its value. Given this, getters and setters are also known as accessors and mutators, respectively.

Does getter and setter speed up compilation?

Getters and setters can speed up compilation. Getters and setters provide encapsulation of behavior. Getters and setters provide a debugging point for when a property changes at runtime.


2 Answers

In V8:

A function that is so short and doesn't have context allocated variables will get inlined. Unless of course too much inlining has already accumulated, in which case the call is still very cheap as the entire executing part of function fits in a 64 byte instruction cache line.

Context allocated variables happen when your function uses for example arguments without being in strict mode or defines inner functions that reference the function's variables. Another problem is that on x64 functions cannot be inlined if the caller and callee cannot share the same context, so all in all, avoid closures like the plague.

See: http://jsperf.com/312319sakd although it looks like firefox uses dead code elimination (which is frustrating cos why waste time doing that?).


Bonus: this jsperf deliberately makes the getter function non-inlinable (through the huge comment which will make the function-size heuristic fail) in current V8. You can see that even if the function wasn't inlined, it's still only 25% slower than referencing the prop directly.

Note that when a function cannot be inlined it is considered a black box whose side effects are not known to the calling function, so the speed is highly context sensitive to the code.

like image 110
Esailija Avatar answered Sep 27 '22 22:09

Esailija


You don't need to create redundant getters/setters functions like this in JavaScript. If you at a later stage require some validation when setting a property or some preparation when getting a property you can do this.

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

... and not alter the usage of the object.

like image 35
user3654410 Avatar answered Sep 27 '22 23:09

user3654410