Getter function speed versus direct access

I recently started using more getter functions rather than direct access to make my code more flexible. I'm curious what the cost of this is in terms of speed. Suppose 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 slight speed difference between the following two statements?

 print(star.planet) print(star.getPlanet()) 
+8
performance javascript getter
source share
2 answers

In V8:

A function that is so short and has no context-sensitive variables will go into it. Unless, of course, too many inlays have already accumulated, in which case the call is still very cheap, since the entire executable part of the function fits into the command cache line of 64 bytes.

The listed context variables occur when your function uses, for example, arguments , not in strict mode or defines internal functions that reference function variables. Another problem is that x64 functions cannot be inlined if the caller and the callee cannot use the same context, so generally avoid closures like the plague.

See: http://jsperf.com/312319sakd , although firefox seems to be using dead code removal (which is disappointing, why waste time on this?).


Bonus: this jsperf deliberately makes the getter function impracticable (through a huge comment that will result in a heuristic failure in functional size) in the current V8. You can see that even if the function was not built in, it is still only 25% slower than the link to prop directly.

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

+10
source share

You do not need to create redundant getters / seters functions like this in JavaScript. If at a later stage you require some checking when setting up the property or some preparation when getting the 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 do not change the use of the object.

+1
source share

All Articles