Extend function comparisons

JavaScript performance comparison

Revision 3 of this test case created by John Cockrell

Info

Comparing jQuery and Underscore extend() functions for performance.

Preparation code

<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="//sjhcockrell.s3.amazonaws.com/downloads/belt.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/1.0.0-rc.3/lodash.min.js"></script>
<script>
var lodash = _.noConflict();
</script>
<script>
Benchmark.prototype.setup = function() {
    var targetObject,
        extendingObject,
        targetArray = [],
        extendingArray = [];
   
   
    //  Populate Arrays.
    for (var i = 0; i < 10000; i += 1) {
        targetArray[i] = i;
        extendingArray[i] = (i * 12) / 3;
    }
   
    targetObject = {
            a: [],
            b: {
                one: "one",
                two: {
                  point1: 2.1,
                  point2: 2.2,
                  point3: 2.3
                },
                three: [3.1, 3.2, 3.3, 3.4]
            },
            c: function(b) { b = 1; return b },
            d: "okay",
            e: 1
        };
   
    extendingObject = {
       prop: function(){ return "prop"; },
       d: targetArray,
       f: function getE() { this.e = this.e * 1000; return this.e; }
    };
   
    var objectTypes = {
        'boolean': false,
        'function': true,
        'object': true,
        'number': false,
        'string': false,
        'undefined': false
    };
   
    var X = {
        extend: function(object, source, guard) {
            var index,
                iteratee = object,
                result = object;
   
            if (!object) return result;
   
            var argsIndex = 1,
                argsLength = typeof guard == 'number' ? 2 : arguments.length;
   
            for (;argsIndex < argsLength; argsIndex++) {
                if ((iteratee = arguments[argsIndex])) {
                    var skipProto = typeof iteratee == 'function' && propertyIsEnumerable.call(iteratee, 'prototype');
   
                    var ownIndex = -1,
                        ownProps = objectTypes[typeof iteratee] ? nativeKeys(iteratee) : [],
                        length = ownProps.length;
   
                    while (++ownIndex < length) {
                        index = ownProps[ownIndex];
                        if (!(skipProto && index == 'prototype')) {
                            result[index] = iteratee[index]
                        }
                    }
                }
            }
   
            return result;
        }
    };
};
</script>

Preparation code output

Test runner

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

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
jQuery.extend()
$.extend(targetObject, extendingObject);
pending…
Belt.extend
B.extend(targetObject, extendingObject);
pending…
lodash.extend
lodash.extend(targetObject, extendingObject);
pending…
X.extend
// Cleaned up version of lodash.
X.extend(targetObject, extendingObject);
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