Object keys iteration

JavaScript performance comparison

Revision 43 of this test case created

Info

Testing object own property iteration + callbacks.

Preparation code

<script>


var data = {};
var k;

function noop (x) { return k = !!x; };

for (var i = 0; i < 128; i++) {  
   data[i] =  'user ' + i;
}

function hasOwnProp (obj, prop) { return Object.prototype.hasOwnProperty(obj, prop); }

var kall = Function.prototype.call;

var boundCall = Function.prototype.call.call.bind(Function.prototype.call);


function itr1 (obj, callback, thisArg) {
        var keys = Object.getOwnPropertyNames(obj);
        var len = keys.length;
        var i;

        for (i = 0; i < len; i++) {
                callback.call(thisArg, obj[keys[i]], keys[i], obj);
        }
}


function itr2 (obj, callback, thisArg) {
        var keys = Object.getOwnPropertyNames(obj);
        var len = keys.length;
        var i;
        var keyI;

        for (i = 0; i < len; i++) {
                keyI = keys[i];
                callback.call(thisArg, obj[keyI], keyI, obj);
        }
}

function itr3 (obj, callback, thisArg) {
        var keys = Object.getOwnPropertyNames(obj);
        var len = keys.length;
        var i;
        var keyI;

        for (i = 0; i < len; i++) {
                keyI = keys[i];
                Function.prototype.call.call(callback, thisArg, obj[keyI], keyI, obj);
        }
}

function itr4 (obj, callback, thisArg) {
        var keys = Object.getOwnPropertyNames(obj);
        var len = keys.length;
        var i;
        var keyI;

        for (i = 0; i < len; i++) {
                keyI = keys[i];
                kall.call(callback, thisArg, obj[keyI], keyI, obj);
        }
}

function itr5 (obj, callback, thisArg) {
        var keys = Object.getOwnPropertyNames(obj);
        var len = keys.length;
        var i;
        var keyI;

        for (i = 0; i < len; i++) {
                keyI = keys[i];
                boundCall(callback, thisArg, obj[keyI], keyI, obj);
        }
}

function itr6 (obj, callback, thisArg) {
        var keys = Object.getOwnPropertyNames(obj);
        var len = keys.length;
        var i;
        var keyI;
        var callit = Function.prototype.call;

        for (i = 0; i < len; i++) {
                keyI = keys[i];
                callit.call(callback, thisArg, obj[keyI], keyI, obj);
        }
}


function forInItr (obj, callback, thisArg) {
        for (var key in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, key))
                callback.call(this, obj[key], key, obj);
        }
}

function forInItrCachedHasOwn (obj, callback, thisArg) {
        var hasOwn = Object.prototype.hasOwnProperty;
        for (var key in obj) {
            if (hasOwn.call(obj, key))
                callback.call(thisArg, obj[key], key, obj);
        }
}

var forIn_functionCachedHasOwn = (function () {
        var hasOwn = Object.prototype.hasOwnProperty;
        return function (obj, callback, thisArg) {
                for (var key in obj) {
                    if (hasOwn.call(obj, key))
                        callback.call(thisArg, obj[key], key, obj)
                }
        };
})();

var forIn_functionCachedHasOwnAndCall = (function () {
        var hasOwn = Object.prototype.hasOwnProperty;
        var zCall = Function.prototype.call;
        return function (obj, callback, thisArg) {
                for (var key in obj) {
                    if (hasOwn.call(obj, key))
                        zCall.call(callback, thisArg, obj[key], key, obj)
                }
        };
})();

var forIn_cachedHasOwnDirectFunc = (function () {
        var hasOwn = Object.prototype.hasOwnProperty;
        return function (obj, callback, thisArg) {
                for (var key in obj) {
                    if (hasOwn.call(obj, key))
                        Function.prototype.call.call(callback, thisArg, obj[key], key, obj)
                }
        };
})();


var itrScopedCall = (function () {

        var callme = Function.prototype.call;

        return function itr2 (obj, callback, thisArg) {
                var keys = Object.getOwnPropertyNames(obj);
                var len = keys.length;
                var i;
                var keyI;

                for (i = 0; i < len; i++) {
                        keyI = keys[i];
                        callme.call(callback, thisArg, obj[keyI], keyI, obj);
                }
        }


})();


var itrScopedCallAndGetOwn = (function () {

        var callme = Function.prototype.call;
        var getOwn = Object.getOwnPropertyNames;

        return function itr2 (obj, callback, thisArg) {
                var keys = getOwn(obj);
                var len = keys.length;
                var i;
                var keyI;

                for (i = 0; i < len; i++) {
                        keyI = keys[i];
                        callme.call(callback, thisArg, obj[keyI], keyI, obj);
                }
        }
})();



var itrScopedCallAndGetOwnStrict = (function () { 'use strict';

        var callme = Function.prototype.call;
        var getOwn = Object.getOwnPropertyNames;

        return function itr2 (obj, callback, thisArg) {
                var keys = getOwn(obj);
                var len = keys.length;
                var i;
                var keyI;

                for (i = 0; i < len; i++) {
                        keyI = keys[i];
                        callme.call(callback, thisArg, obj[keyI], keyI, obj);
                }
        }
})();






function finalForEachOwnProperty (obj, callback, thisArg) {
        var i, len, prop, keys = Object.getOwnPropertyNames(obj);
        for (i = 0, len = keys.length; i < len; i++)
                callback.call(thisArg, obj[prop = keys[i]], prop, obj);
}




var forIn_scopeCachedHasOwn_localCachedCall = (function () {
        var hasOwn = Object.prototype.hasOwnProperty;
        return function (obj, callback, thisArg) {
                var callIt = Function.prototype.call;
                for (var key in obj) {
                    if (hasOwn.call(obj, key))
                        callIt.call(callback, thisArg, obj[key], key, obj)
                }
        };
})();


var forIn_paramCachedHasOwnAndCall = (function (hasOwn, callIt) {
        return function (obj, callback, thisArg) {
                for (var key in obj) {
                    if (hasOwn.call(obj, key))
                        callIt.call(callback, thisArg, obj[key], key, obj)
                }
        };
})(Object.prototype.hasOwnProperty, Function.prototype.call);


/*
var itr_scopeCachedGetOwn = (function () {
        var getOwn = Object.getOwnPropertyNames;
        function finalForEachOwnProperty (obj, callback, thisArg) {
                var i, len, prop, keys = Object.getOwnPropertyNames(obj);
                for (i = 0, len = keys.length; i < len; i++)
                        callback.call(thisArg, obj[prop = keys[i]], prop, obj);
        }
})()*/





var itr_paramCachedForEachAndGetOwn = (function (own, cal) {
        return function (obj, callback, thisArg) {
                var i, len, prop, keys = own(obj);
                for (i = 0, len = keys.length; i < len; i++)
                        cal.call(callback, thisArg, obj[prop = keys[i]], prop, obj);
        };
})(Object.getOwnPropertyNames, Function.prototype.call);



var itr_paramCachedCall = (function (cal) {
        return function (obj, callback, thisArg) {
                var i, len, prop, keys = Object.getOwnPropertyNames(obj);
                for (i = 0, len = keys.length; i < len; i++)
                        cal.call(callback, thisArg, obj[prop = keys[i]], prop, obj);
        };
})(Function.prototype.call);



</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
itr1(data, noop);
pending…
itr2(data, noop);
pending…
itr3(data, noop);
pending…
itr4(data, noop);
pending…
var thisArg = undefined;
for (var key in data) {
    if (data.hasOwnProperty(key))
        noop.call(thisArg, data[key], key, data)
}
pending…
var hasOwnProperty = Object.prototype.hasOwnProperty;
var thisArg = undefined;
for (var key in data) {
    if (hasOwnProperty.call(data, key))
        noop.call(thisArg, data[key], key, data)
}
pending…
itr5(data, noop);
pending…
for (var key in data) {
    if (hasOwnProp(data, key))
        noop(data[key], key, data)
}
pending…
for (var key in data) {
    if (Object.prototype.hasOwnProperty(data, key))
        noop(data[key], key, data)
}
pending…
forInItr(data, noop);
pending…
itr6(data, noop);
pending…
forInItrCachedHasOwn(data, noop);
pending…
forIn_functionCachedHasOwn(data, noop);
pending…
forIn_functionCachedHasOwnAndCall(data, noop);
pending…
forIn_cachedHasOwnDirectFunc(data, noop);
pending…
itrScopedCall(data, noop);
pending…
itrScopedCallAndGetOwn(data, noop);
pending…
itrScopedCallAndGetOwnStrict(data, noop);
pending…
finalForEachOwnProperty(data, noop);
pending…
forIn_scopeCachedHasOwn_localCachedCall(data, noop);
pending…
forIn_paramCachedHasOwnAndCall(data, noop);
pending…
itr_paramCachedForEachAndGetOwn(data, noop);
pending…
itr_paramCachedCall(data, noop);
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