class-perfs (v2)

Revision 2 of this benchmark created on


Preparation HTML

<script src='http://documentcloud.github.com/underscore/underscore.js'></script>
<script src='http://documentcloud.github.com/backbone/backbone-min.js'></script>
<script src='http://aralejs.org/dist/seajs/1.1.0/sea.js'></script>
<script src='http://aralejs.org/dist/class/0.9.0/class.js'></script>
<script>
seajs.use('class/0.9.0/class', function(Class) {
  seajs.Class = Class;
});
</script>
<script src='http://mootools.net/download/get/mootools-core-1.4.5-full-nocompat.js'></script>

Setup

var context = window
        , old = context.klass
        , f = 'function'
        , fnTest = /xyz/.test(function () {xyz}) ? /\bsupr\b/ : /.*/
        , proto = 'prototype'
    
      function klass(o) {
        return extend.call(isFn(o) ? o : function () {}, o, 1)
      }
    
      function isFn(o) {
        return typeof o === f
      }
    
      function wrap(k, fn, supr) {
        return function () {
          var tmp = this.supr
          this.supr = supr[proto][k]
          var ret = fn.apply(this, arguments)
          this.supr = tmp
          return ret
        }
      }
    
      function process(what, o, supr) {
        for (var k in o) {
          if (o.hasOwnProperty(k)) {
            what[k] = isFn(o[k])
              && isFn(supr[proto][k])
              && fnTest.test(o[k])
              ? wrap(k, o[k], supr) : o[k]
          }
        }
      }
    
      function extend(o, fromSub) {
        // must redefine noop each time so it doesn't inherit from previous arbitrary classes
        function noop() {}
        noop[proto] = this[proto]
        var supr = this
          , prototype = new noop()
          , isFunction = isFn(o)
          , _constructor = isFunction ? o : this
          , _methods = isFunction ? {} : o
        function fn() {
          if (this.initialize) this.initialize.apply(this, arguments)
          else {
            fromSub || isFunction && supr.apply(this, arguments)
            _constructor.apply(this, arguments)
          }
        }
    
        fn.methods = function (o) {
          process(prototype, o, supr)
          fn[proto] = prototype
          return this
        }
    
        fn.methods.call(fn, _methods).prototype.constructor = fn
    
        fn.extend = arguments.callee
        fn[proto].implement = fn.statics = function (o, optFn) {
          o = typeof o == 'string' ? (function () {
            var obj = {}
            obj[o] = optFn
            return obj
          }()) : o
          process(this, o, supr)
          return this
        }
    
        return fn
      }
    
      klass.noConflict = function () {
        context.klass = old
        return this
      }
      context.klass = klass

Test runner

Ready to run.

Testing in WebKit 537.36 / undefined
TestOps/sec
backbone
var Animal = Backbone.Model.extend({
  initialize: function(name) {
    this.name = name;
  },
  talk: function() {
    return 'I am ' + this.name;
  }
});

var Bird = Animal.extend({
  initialize: function(name) {
    Animal.prototype.initialize.call(this, name);
  },
  fly: function() {
    return 'I am flying';
  }
});

new Animal();
var bird = new Bird();
bird.talk();
bird.fly();
ready
mootools
var Animal = new Class({
  initialize: function(name) {
    this.name = name;
  },
  talk: function() {
    return 'I am ' + this.name;
  }
});

var Bird = new Class({
  Extends: Animal,
  initialize: function(name) {
    this.parent(name);
  },
  fly: function() {
    return 'I am flying';
  }
});

new Animal();
var bird = new Bird();
bird.talk();
bird.fly();
ready
arale
var Animal = seajs.Class.create({
  initialize: function(name) {
    this.name = name;
  },
  talk: function() {
    return 'I am ' + this.name;
  }
});

var Bird = Animal.extend({
  initialize: function(name) {
    Bird.superclass.initialize.call(this, name);
  },
  fly: function() {
    return 'I am flying';
  }
});

new Animal();
var bird = new Bird();
bird.talk();
bird.fly();
ready
klass
var Animal = klass({
  initialize: function(name) {
    this.name = name;
  },
  talk: function() {
    return 'I am ' + this.name;
  }
});

var Bird = Animal.extend({
  initialize: function(name) {
    this.supr(name);
  },
  fly: function() {
    return 'I am flying';
  }
});

new Animal();
var bird = new Bird();
bird.talk();
bird.fly();
ready

Revisions

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