Performance of Array vs. Object

JavaScript performance comparison

Revision 85 of this test case created by Digitale Welten and last updated

Info

Some concepts to loop through an whole array of objects (non-literal).

Preparation code

<script>

// test arrays
var arr = [];
var obj = {};
var obj2 = new Object();
var obj3 = new (function(){
    var $obj3 = function(){
        this.obj = (function(){
            var obj3 = {};
            for(var i = 0; i < 10000; ++i) {
                obj3[i] = { payload: i };
            }
            return obj3;
        }());
    };
    $obj3.prototype.getSum = function() {
        var obj = this, sum = 0;
        for(var key in obj) {
            if(obj.hasOwnProperty(key)) sum += obj[key].payload;  
            return sum;
        }    
    };
    return $obj3;
}());
var sparse = [];
var breaker = {};



//
obj2.constructor.prototype.getKeys = function(){ return Object.keys(this); };
obj2.constructor.prototype.getSum = function(){
    var obj = this, sum = 0, len = obj.getKeys().length;
    for(var i = 0; i < len; ++i) sum += obj[i].payload;  
    return sum;
};
// forEach for assoziative arrays
obj2.constructor.prototype.each = function(obj, iterator, context) {
    //var key; //var obj = this;
    for(var key in obj) {
        if(obj.hasOwnProperty(key)) {
            if(iterator.call(context, obj[key], key, obj) === breaker) return;
        }
    }    
 };
// object array to simple array
obj2.constructor.prototype.getValuesPush = function() {
    var obj = this, values = [];
    for(var key in obj) if(obj.hasOwnProperty(key)) values.push(obj[key]);
    return values;
};

// object array to simple array
obj2.constructor.prototype.getValuesIterate = function() {
    var obj = this, values = [], len = 0;
    for(var key in obj) if(obj.hasOwnProperty(key)) values[len++] = obj[key];
    return values;
};

// object array to simple array
obj2.constructor.prototype.getValuesIndexed = function() {
    var obj = this, len = obj.getKeys().length, values = [];
    for(var i = 0; i < len; ++i) values[i] = obj[i];
    return values;
};


// forEach for assoziative arrays
var each = function(obj, iterator, context) {
    for(var key in obj) {
        if(obj.hasOwnProperty(key)) {
            if(iterator.call(context, obj[key], key, obj) === breaker) return;
        }
    }    
 };


// create arrays
for(var i = 0; i < 10000; ++i) {
  arr.push({ payload: i });
  obj[i] = { payload: i };
  obj2[i] = { payload: i };
  obj3[i] = { payload: i };
}

// create sparsed array
sparse [0] = "a";
sparse [10] = "b";
sparse [9999] = "c";

// cached keys
var keys = Object.keys(obj);



//console.log(obj.getValuesIndexed());
</script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
Simple Array [ ] of Objects
var sum = 0, x = 0, len = arr.length;

for (; x < len; ++x) {

  sum += arr[x].payload;
}

if(sum!=49995000) console.log('error: '+sum);
pending…
Object Array { } of Objects
var sum = 0;

for (var x in obj) {

  if(obj.hasOwnProperty(x)) sum += obj[x].payload;
}

if(sum!=49995000) console.log('error: '+sum);
pending…
Object Iterate (known length)
var sum = 0, x = 0;

for (; x < 10000; ++x) {

  sum += obj[x].payload;
}

if(sum!=49995000) console.log('error: '+sum);
pending…
Object > keys() Iterate
var sum = 0, x = 0, len = keys.length;

for (; x < len; ++x) {

  sum += obj[keys[x]].payload;
}

if(sum!=49995000) console.log('error: '+sum);
pending…
Array.foreach()
var sum = 0;

arr.forEach(function(val) {

    sum += val.payload;
});

if(sum!=49995000) console.log('error: '+sum);
pending…
Object > keys().foreach()
var sum = 0;

keys.forEach(function(val) {

    sum += obj[val].payload;
});

if(sum!=49995000) console.log('error: '+sum);
pending…
Using Array.reduce()
var sum = arr.reduce(function(a, b) {
    return a.payload + b.payload;
});

if(sum!=49995000) console.log('error: '+sum);
pending…
Object.foreach() Polyfill
var sum = 0;

each(obj, function(val) {

    sum += val.payload;
});

if(sum!=49995000) console.log('error: '+sum);
pending…
Object > Array.foreach() Prototype Push
var sum = 0;

obj2.getValuesPush().forEach(function(val) {

    sum += val.payload;
});

if(sum!=49995000) console.log('error: '+sum);
pending…
Object > Array.foreach() Prototype Iterate
var sum = 0;

obj2.getValuesIterate().forEach(function(val) {

    sum += val.payload;
});

if(sum!=49995000) console.log('error: '+sum);
pending…
Object > Array.foreach() Prototype Indexed
var sum = 0;

obj2.getValuesIndexed().forEach(function(val) {

    sum += val.payload;
});

if(sum!=49995000) console.log('error: '+sum);
pending…
Object > Keys.foreach() non-cached
var sum = 0;
var key = obj2.getKeys();

key.forEach(function(val) {

    sum += obj[val].payload;
});

if(sum!=49995000) console.log('error: '+sum);
pending…
Object.foreach() Prototype Polyfill
var sum = 0;

obj2.each(function(val) {

    sum += val.payload;
});

if(sum!=49995000) console.log('error: '+sum);
pending…
Internal Routine via Object Prototype
var sum = obj2.getSum(obj);

if(sum!=49995000) console.log('error: '+sum);
pending…
Internal Routine via Function Prototype
var sum = obj3.getSum();

if(sum!=49995000) console.log('error: '+sum);
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL. Here’s a list of current revisions for this page:

0 comments

Add a comment