Skip to content

Instantly share code, notes, and snippets.

@stefanpenner
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stefanpenner/6c1dd5b68feb771c9d8a to your computer and use it in GitHub Desktop.
Save stefanpenner/6c1dd5b68feb771c9d8a to your computer and use it in GitHub Desktop.

testing various super mechanism including es6 super in 41.0.2249.0 canary (64-bit) Looks like es6 super needs some perf tuning.

// 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(); } },
])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment