Henry
Henry

Reputation: 587

why are variables in javascript much slower?

var completeObj = {a: { b: { c: { d: { e: { f: 23 } } } } } };
var funcA = function(obj){
    var a = 'a',b='b',c='c',d='d',e='e',f='f';
    return obj[a][b][c][d][e][f];
}

var funcB = function(obj){
    return obj['a']['b']['c']['d']['e']['f'];
}

funcA is much slower than funcB,looking for varible in scope cost so much time? test url : http://jsperf.com/static-and-dynamic-argument thx

Upvotes: 2

Views: 156

Answers (3)

Esailija
Esailija

Reputation: 140236

It has nothing to do with variables or variable scope (pure local variables are actually free) but using reflection to access properties rather than constants.

obj['a']['b']['c']['d']['e']['f'];

is equal to obj.a.b.c.d.e.f so it is known even from the source code what properties will be accessed.

However, using bracket notation with variables requires figuring out at runtime what properties will be accessed and so it's completely different. In Java the former code is like using Reflection library to access properties whereas latter is same as using normal static dot access.


So why doesn't the compiler "realize" that the variables are static too? Well your code is completely unreasonable and JIT wasting time optimizing unreasonable code is a bad JIT.

Why does it realize that ['a'] is same as .a though? Well at least in my experience it was much simpler to have parser spit out same MemberAccess objects for dot and bracket access and then just check if the expression is a constant string.

Upvotes: 1

c.P.u1
c.P.u1

Reputation: 17094

It is because local variables(function-scope) become properties of an internal Variable object. So a call to obj[a][b][c][d][e][f] ends up accessing properties a through f on the Variable object first and then on completeObj.

Upvotes: 1

Stephen
Stephen

Reputation: 5470

http://jsperf.com/static-and-dynamic-argument/2

I took your test cases and added one to it to 'prove a point'. When you access somthing in an object via the ['key'] notation, you're doing the same thing as accessing it via .key. The compiler is smart enough to know that ['a'] is equivalent to .a. However, when you stick a variable in there, as Bergi mentioned in his comment, the compiler has no idea that [a] is actually ['a'].

Upvotes: 2

Related Questions