Inheritance performance - method calls (v12)

Revision 12 of this benchmark created by kogarashisan1 on


Description

Accurate tests of JavaScript class inheritance models.

These tests aim to provide adequate and accurate results by modelind real-life application behaviour and avoiding common pitfalls. For source code and detailed explanation - please visit the repository:

https://github.com/kogarashisan/PerfTests

Tested libraries does not include Prototype or MooTools, cause they are slow. Ext.JS is not included, cause it affects results of other tests.

*** IF CURRENT PAGE IS BROKEN - then visit repository for the link to proper version. ***

Preparation HTML

<script src="http://kogarashisan.github.io/PerfTests/export/dependencies-v2.js"></script>
<script src="http://kogarashisan.github.io/PerfTests/export/bundle-v2.js"></script>
<script>

//https://github.com/Josenzo/inherit.js
var inherit=function(){"use strict";function h(a,b){return"object"==typeof a?(d=new Function,d[e]=a):(d=a,a[e].hasOwnProperty(f)&&a[e][f]!==a||(d[e]="object"==typeof b?new a(b,b[f]):new a)),d}function i(c,d){a=g(c);for(b in d)a[b]=d[b];return a}var a,b,c,d,e="prototype",f="constructor",g=Object.create;return function j(a,b){var k=arguments;return k.length>2?(Array.prototype.splice.call(k,0,2,j(a,b)),j.apply(this,k)):(c=h(1==k.length?{}:a),d=h(k[k.length-1],g(c[e])),d[e].hasOwnProperty(f)||(d[e][f]=new Function),d[e][f][e]=i(c[e],d[e]),d[e][f].$super=g(c[e]),d[e][f][e][f]=d[e][f],d[e][f])}}();

var InheritParent = inherit(function () {var cache_buster_0801;
    this.constructor = function (instance_string) {var cache_buster_0802;
        this.counter         = 0;
        this.instance_array  = [];
        this.instance_string = instance_string;
    };

    this.method = function (prevent_inline) {var cache_buster_0803;
        if (this.counter > 99)
            this.counter = this.counter / 2;
        else this.counter++;

        if (prevent_inline) {
            var i = 0;
            for (i = 0; i < 1; i++) dummy.method();
            for (i = 0; i < 1; i++) dummy.method();
            for (i = 0; i < 1; i++) dummy.method();
            for (i = 0; i < 1; i++) dummy.method();
            for (i = 0; i < 1; i++) dummy.method();
            for (i = 0; i < 1; i++) dummy.method();
            for (i = 0; i < 1; i++) dummy.method();
            for (i = 0; i < 1; i++) dummy.method();
            for (i = 0; i < 1; i++) dummy.method();
            for (i = 0; i < 1; i++) dummy.method();
        }
    };
});

var InheritChildA = inherit(InheritParent, function ($super) {var cache_buster_0804;
    this.constructor = function (instance_string) {var cache_buster_0805;
        this.member_a = 1;
        $super.constructor.call(this, instance_string);
    };

    this.method = function () {var cache_buster_0806;
        this.member_a =- this.member_a;
        $super.method.call(this, false);
    };
});

var InheritChildB = inherit(InheritParent, function ($super) {var cache_buster_0807;
    this.constructor = function (instance_string) {var cache_buster_0808;
        this.member_b =- 1;
        $super.constructor.call(this, instance_string);
    };

    this.method = function () {var cache_buster_0809;
        this.member_b =- this.member_b;
        $super.method.call(this, false);
    };
});

/*
Each model exports two children into window, for example:
        TypeScriptChildA and TypeScriptChildB

This code creates 5 instances of each child for each model
and stores them in global model_instances array.

Model test then can be done as follows:

var instances = model_instances[0]; // TypeScript
// just a large loop
for (var i = 0; i < 100000; i++) {
        // call `method` on each of 10 different instances
        for (var c = 0; c < 10; c++) {
                instances[c].method();
        }
}
*/

var model_names = [
        /* 0  */'TypeScript',
        /* 1  */'CMBrowserMono', // ClassManager
        /* 2  */'CMBrowserPoly', // ClassManager
        /* 3  */'CMServerFullrefMono', // ClassManager
        /* 4  */'CMServerPartialrefMono', // ClassManager
        /* 5  */'CMServerPartialrefPoly', // ClassManager
        /* 6  */'DNW_IW_', // DotNetWise inheritWith
        /* 7  */'DNW_FC_', // DotNetWise fastClass
        /* 8  */'Fiber',
        /* 9  */'JR', // John Resig
        /* 10 */'NativeUnwrapped',
        /* 11 */'NativeWrapped',
        /* 12 */'Klass', // klass
        /* 13 */'AugmentClassical', // augment
  "Inherit"
];

var model_instances = [];

for (var model_index = 0; model_index < model_names.length; model_index++) {
        var constructorA = window[model_names[model_index] + 'ChildA'];
        var constructorB = window[model_names[model_index] + 'ChildB'];
        model_instances[model_index] = [
                new constructorA("a1"),
                new constructorB("b1"),
                new constructorA("a2"),
                new constructorB("b2"),
                new constructorA("a3"),
                new constructorB("b3"),
                new constructorA("a4"),
                new constructorB("b4"),
                new constructorA("a5"),
                new constructorB("b5")
        ];

        // warm-up loop
        for (var dummy = 0; dummy < 5; dummy++) {
                for (var c = 0; c < 10; c++) {
                        model_instances[model_index][c].method();
                }
        }
}
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
TypeScript
var instances = model_instances[0]; // TypeScriptChildX
for (var i = 0; i < 50000; i++) {
    for (var c = 0; c < 10; c++) {
        instances[c].method();
    }
}
ready
ClassManager / Browser / Monomorphic
var instances = model_instances[1]; // CMBrowserMonoChildX
for (var i = 0; i < 50000; i++) {
    for (var c = 0; c < 10; c++) {
        instances[c].method();
    }
}
ready
ClassManager / Browser / Polymorphic
var instances = model_instances[2]; // CMBrowserPolyChildX
for (var i = 0; i < 50000; i++) {
    for (var c = 0; c < 10; c++) {
        instances[c].method();
    }
}
ready
ClassManager / Server / Monomorphic / Full
var instances = model_instances[3]; // CMServerFullrefMonoChildX
for (var i = 0; i < 50000; i++) {
    for (var c = 0; c < 10; c++) {
        instances[c].method();
    }
}
ready
ClassManager / Server / Monomorphic / Partial
var instances = model_instances[4]; // CMServerPartialrefMonoChildX
for (var i = 0; i < 50000; i++) {
    for (var c = 0; c < 10; c++) {
        instances[c].method();
    }
}
ready
ClassManager / Server / Polymorphic / Partial
var instances = model_instances[5]; // CMServerPartialrefPolyChildX
for (var i = 0; i < 50000; i++) {
    for (var c = 0; c < 10; c++) {
        instances[c].method();
    }
}
ready
DotNetWise inheritWith
var instances = model_instances[6]; // DNW_IW_ChildX
for (var i = 0; i < 50000; i++) {
    for (var c = 0; c < 10; c++) {
        instances[c].method();
    }
}
ready
DotNetWise fastClass
var instances = model_instances[7]; // DNW_FC_ChildX
for (var i = 0; i < 50000; i++) {
    for (var c = 0; c < 10; c++) {
        instances[c].method();
    }
}
ready
Fiber
var instances = model_instances[8]; // FiberChildX
for (var i = 0; i < 50000; i++) {
    for (var c = 0; c < 10; c++) {
        instances[c].method();
    }
}
ready
John Resig
var instances = model_instances[9]; // JRChildX
for (var i = 0; i < 50000; i++) {
    for (var c = 0; c < 10; c++) {
        instances[c].method();
    }
}
ready
Native (unwrapped)
var instances = model_instances[10]; // NativeUnwrappedChildX
for (var i = 0; i < 50000; i++) {
    for (var c = 0; c < 10; c++) {
        instances[c].method();
    }
}
ready
Native (wrapped)
var instances = model_instances[11]; // NativeWrappedChildX
for (var i = 0; i < 50000; i++) {
    for (var c = 0; c < 10; c++) {
        instances[c].method();
    }
}
ready
klass
var instances = model_instances[12]; // KlassChildX
for (var i = 0; i < 50000; i++) {
    for (var c = 0; c < 10; c++) {
        instances[c].method();
    }
}
ready
augment
var instances = model_instances[13]; // AugmentClassicalChildX
for (var i = 0; i < 50000; i++) {
    for (var c = 0; c < 10; c++) {
        instances[c].method();
    }
}
ready
Inherit
var instances = model_instances[14];
for (var i = 0; i < 50000; i++) {
    for (var c = 0; c < 10; c++) {
        instances[c].method();
    }
}
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.

  • Revision 2: published by kogarashisan1 on
  • Revision 3: published by kogarashisan1 on
  • Revision 4: published by Billy Tetrud on
  • Revision 5: published by Billy Tetrud on
  • Revision 6: published by Billy Tetrud on
  • Revision 7: published by kogarashisan1 on
  • Revision 9: published by Aadit M Shah on
  • Revision 10: published by kogarashisan1 on
  • Revision 11: published by Enzo on
  • Revision 12: published by kogarashisan1 on