testing various super mechanism including es6 super in 41.0.2249.0 canary (64-bit) Looks like es6 super needs some perf tuning.
- runnable: http://static.iamstef.net/super
// es6 super
bar.name x 91,370,164 ops/sec ±2.39% (61 runs sampled)
foo.name x 9,165,519 ops/sec ±4.14% (58 runs sampled)
baz.name x 4,946,119 ops/sec ±3.47% (46 runs sampled)
// explicit manual inlining
bar.otherName x 94,934,476 ops/sec ±2.49% (60 runs sampled)
foo.otherName x 41,962,623 ops/sec ±2.94% (61 runs sampled)
baz.otherName x 23,638,438 ops/sec ±2.31% (61 runs sampled)
// Parent.prototype.method.call(..)
bar.traditionalName x 98,940,355 ops/sec ±3.45% (60 runs sampled)
foo.traditionalName x 73,616,189 ops/sec ±3.69% (61 runs sampled)
baz.traditionalName x 55,552,493 ops/sec ±3.62% (59 runs sampled)
// es6 toMethodName
bar.toMethodName x 97,245,227 ops/sec ±2.50% (60 runs sampled)
foo.toMethodName x 9,865,538 ops/sec ±3.03% (60 runs sampled)
baz.toMethodName x 5,172,785 ops/sec ±3.60% (59 runs sampled)
// ember style super via wrapping
bar.emberName x 98,860,284 ops/sec ±2.30% (60 runs sampled)
foo.emberName x 28,707,870 ops/sec ±2.81% (61 runs sampled)
baz.emberName x 14,306,060 ops/sec ±2.62% (60 runs sampled)
'use strict';
class Bar {
name( ) {
return 'BAR';
}
otherName() {
return 'BAR';
}
traditionalName() {
return 'BAR';
}
emberName() {
return 'BAR';
}
}
class Foo extends Bar {
name() {
return 'FOO' + super.name();
}
otherName() {
return 'FOO' + this._superBar$otherName();
}
traditionalName() {
return 'FOO' + Bar.prototype.traditionalName.call(this);
}
emberName() {
return 'FOO' + this._super();
}
}
class Baz extends Foo {
name() {
return 'Baz' + super.name();
}
otherName() {
return 'Baz' + this._superFoo$otherName();
}
traditionalName() {
return 'Baz' + Foo.prototype.traditionalName.call(this);
}
emberName() {
return 'Baz' + this._super();
}
}
function giveMethodSuper(_super, fn) {
return function() {
var previousSuper = this._super;
this._super = _super;
var result = fn.apply(this, arguments);
this._super = previousSuper;
return result;
}
};
Bar.prototype.emberName = function() {
return 'BAR';
};
Foo.prototype.emberName = giveMethodSuper(Bar.prototype.emberName, Foo.prototype.emberName);
Baz.prototype.emberName = giveMethodSuper(Foo.prototype.emberName, Baz.prototype.emberName);
Bar.prototype.toMethodName = function() {
return 'BAR';
};
Foo.prototype.constructor = Foo;
Foo.prototype.toMethodName = function () {
return 'FOO' + super.name();
}.toMethod(Foo.prototype);
Baz.prototype.constructor = Baz;
Baz.prototype.toMethodName = function () {
return 'Baz' + super.name();
}.toMethod(Baz.prototype);
Foo.prototype._superBar$otherName = Bar.prototype.otherName;
Baz.prototype._superFoo$otherName = Foo.prototype.otherName;
var bar = new Bar();
var foo = new Foo();
var baz = new Baz();
var assert = require('assert');
assert(bar.name() === 'BAR');
assert(foo.name() === 'FOOBAR');
assert(baz.name() === 'BazFOOBAR');
assert(bar.otherName() === 'BAR');
assert(foo.otherName() === 'FOOBAR');
assert(baz.otherName() === 'BazFOOBAR');
assert(bar.traditionalName() === 'BAR');
assert(foo.traditionalName() === 'FOOBAR');
assert(baz.traditionalName() === 'BazFOOBAR');
assert(bar.toMethodName() === 'BAR');
assert(foo.toMethodName() === 'FOOBAR');
assert(baz.toMethodName() === 'BazFOOBAR');
assert(bar.name() === 'BAR');
assert(foo.emberName() === 'FOOBAR');
assert(baz.emberName() === 'BazFOOBAR');
require('./bench')([
{ name: 'bar.name', fn: function() { return bar.name(); } },
{ name: 'foo.name', fn: function() { return foo.name(); } },
{ name: 'baz.name', fn: function() { return baz.name(); } },
{ name: 'bar.otherName', fn: function() { return bar.otherName(); } },
{ name: 'foo.otherName', fn: function() { return foo.otherName(); } },
{ name: 'baz.otherName', fn: function() { return baz.otherName(); } },
{ name: 'bar.traditionalName', fn: function() { return bar.traditionalName(); } },
{ name: 'foo.traditionalName', fn: function() { return foo.traditionalName(); } },
{ name: 'baz.traditionalName', fn: function() { return baz.traditionalName(); } },
{ name: 'bar.toMethodName', fn: function() { return bar.toMethodName(); } },
{ name: 'foo.toMethodName', fn: function() { return foo.toMethodName(); } },
{ name: 'baz.toMethodName', fn: function() { return baz.toMethodName(); } },
{ name: 'bar.emberName', fn: function() { return bar.emberName(); } },
{ name: 'foo.emberName', fn: function() { return foo.emberName(); } },
{ name: 'baz.emberName', fn: function() { return baz.emberName(); } },
])