Joshua Wise
Joshua Wise

Reputation: 653

Chrome 39 JavaScript Performance Anomaly

I did a jsPerf test to see if there were any performance differences between using arguments or local variables in a function in JavaScript.

In Firefox 34, there was practically no difference. However, in Chrome 39, the compiler seems to be doing a lot of harm. See these results:

Can anyone explain why this happens?

Upvotes: 4

Views: 197

Answers (1)

Vyacheslav Egorov
Vyacheslav Egorov

Reputation: 10492

First of all for a benchmark that tries to measure arguments vs. local variables performance behavior you are doing too much in the each case - you allocate a closure again and again, you allocate object from object literal, you use for-in loop. All these operations are way more expensive than local variable access. Their costs subsume and hide whatever small cost variable access has.

Now the anomaly you are seeing is due to V8 not having a fast path for creating closures that contain literals: there is FastNewClosureStub but it is only used when there are no literals in the closure[1]. This makes closure allocation more expensive in the first case compared to the second - you are seeing this reflected in the score as closure allocation is rather dominant part of your benchmark (it allocates one closure per op).

If you "hide" literal creation[2] into a separate function you will see anomaly going away. Note: such hiding doesn't make benchmark anymore representative: it is still not measuring what you want to measure.

Overall trying to capture performance characteristics of variable access in a benchmark is very hard because these are usually among the fastest and smallest operations even in the code produced by non-optimizing (baseline) compiler. In the most common case when no variables are captured and the scope does not contain with, eval or arguments object - there'll be no difference between arguments and local variable access both compiling down into a single memory load.

[1] https://github.com/v8/v8-git-mirror/blob/9def087efcd844342c35f42628bac4ead49cac81/src/ia32/full-codegen-ia32.cc#L1213-L1218

[2] http://jsperf.com/variable-vs-variable-passed-as-an-argument-to-a-self-in/3

Upvotes: 4

Related Questions