After getting the tip to use JSLitmus for JavaScript microbenchmarks I grabbed my old “How to access JavaScript Object” code and build some tests with JSLitmus. The following question was sometimes very religious and only benchmarks can solve the problem:

The question is simple: what is faster?

obj = {a:1}; //variant 1 result = obj.a; //variant 2 result = obj['a']; //variant 3 - build an object with getter function: result = obj.getA();

I build some variants and run the benchmarks on different browsers on my Intel Atom N270 eeeBox. The examples show the single function call with JSLitmus for better readability, the benchmarks are made with the function-count-parameter.

Live demo

You can start it here with your browser – some tests will result “Infinity” because the tests can be fast on modern Intel Core cpus. That’s one of the reason to use a netbook/netbook with a slow standard Atom cpu. If it run fast on this machine its fast enough for the normal web visitor.





A: Accessing with Dot Notation to a plain Object.

The simple direct access to an JavaScript Object used as key-value data object.

var obj = {a: 1, b: 1, c:1, d:1, e:1}; JSLitmus.test("ObjectAccessWithDot", function() { sum = obj.a + obj.b + obj.c + obj.d + obj.e; } );

B: Accessing with Key Notation to a plain Object.

The access with the name as key to an JavaScript Object used as key-value data object. This should be the same like Case B.

var obj = {a: 1, b: 1, c:1, d:1, e:1}; JSLitmus.test("ObjectAccessWithKey", function() { sum = obj['a'] + obj['b'] + obj['c'] + obj['d'] + obj['e']; } );

If the key is constant a optimizer can convert the code to the dot notation. The second example use local variables for the keys.

var obj = {a: 1, b: 1, c:1, d:1, e:1}; var a='a', b='b', c='c', d='d', e='e'; JSLitmus.test("ObjectAccessWithKey", function() { sum = obj[a] + obj[b] + obj[c] + obj[d] + obj[e]; } );

C/D: Building a constructor, accessing with Dot or Key notation

Plain JavaScript Objects are fine, but we build more complex object and we need contructors. Build an constructor with the five members and get an instance of it for accessing. This should be the same than Case A because type(obj)==”object”.

var Data = function() { this.a=1; this.b=1; this.c=1; this.d=1; this.e=1;}; var obj = new Data(); JSLitmus.test("ConstructorAccessWithDot", function() { sum = obj.a + obj.b + obj.c + obj.d + obj.e; } ); JSLitmus.test("ConstructorAccessWithKey", function() { sum = obj['a'] + obj['b'] + obj['c'] + obj['d'] + obj['e']; } );

E/F: Accessing with getter function to public or private members

The first examples use only direct access to the member variables. Variant E/F use the more java-like getter functions to access to the integers and it should dramaticly slower (function call overhead).

var Data = function() { this.a=1; this.b=1; this.c=1; this.d=1; this.e=1; this.getA = function() { return this.a; } this.getB = function() { return this.b; } this.getC = function() { return this.c; } this.getD = function() { return this.d; } this.getE = function() { return this.e; } }; var obj = new Data(); JSLitmus.test("testConstructorAccessWithGetter", function() { sum = obj.getA() + obj.getB() + obj.getC() + obj.getD() + obj.getE(); } );

Real private members can be generated in the constructor as local variables. They are only accessable with functions defined in the same variable scope. The benchmark will test if the access to the local scope is more expensive than to public members.

var Data = function() { var a=1, b=1, c=1, d=1, e=1; this.getA = function() { return a; } this.getB = function() { return b; } this.getC = function() { return c; } this.getD = function() { return d; } this.getE = function() { return e; } }; var obj = new Data(); JSLitmus.test("testConstructorAccessWithPrivateGetter", function() { sum = obj.getA() + obj.getB() + obj.getC() + obj.getD() + obj.getE();} );

G. Accessing members over the prototype chain

The DataProto contructor defines the five member and the Data constructor will inheritance it. While accessing to the member variables it has to hop to the prototype DataProto to get the values. It should be slower than Case A or Case C.

var DataProto = function() { this.a=1; this.b=1; this.c=1; this.d=1; this.e=1; }; var Data = function() {}; Data.prototype = new DataProto(); var obj = new Data(); JSLitmus.test("ConstructorAccessWithDot", function() { sum = obj.a + obj.b + obj.c + obj.d + obj.e; } );

The results

Funny! If you access to many members use plain JavaScript objects with dot notation. Charts shows loops/second – higher is better!

The Opera 9.80 was a Opera 10.10, the last one is from the Konqueror 4.3.2:



I dont test the IE because it is not a browser for JavaScript Programmers (ECMA5) and I dont run it on ubuntu … If any one will post benchmarks for windows (on an netbook with Intel Atom N270) as tinyurl make a comment!