JavaScript Object Oriented Libraries Benchmark

JavaScript performance comparison

Revision 152 of this test case created by

Preparation code

<script src="http://rawgithub.com/jashkenas/underscore/1.5.2/underscore.js"></script>
<script src="http://rawgithub.com/nicolas-van/ring.js/1.0.0/ring.js"></script>
<script src="http://dl.dropbox.com/u/7677927/oop-benchmark/lib/jsface.js">
</script>
<script src="http://dl.dropbox.com/u/7677927/oop-benchmark/lib/my.class.js">
</script>
<script src="http://dl.dropbox.com/u/7677927/oop-benchmark/lib/jrclass.js">
</script>
<script src="http://dl.dropbox.com/u/7677927/oop-benchmark/lib/klass.js">
</script>
<script src="http://dl.dropbox.com/u/7677927/oop-benchmark/lib/classy.js">
</script>
<script src="http://dl.dropbox.com/u/7677927/oop-benchmark/lib/ptclass.js">
</script>
<script src="https://rawgithub.com/javascript/augment/master/lib/augment.js">
</script>
<script src="http://cdn.sencha.com/ext-4.1.1a-gpl/builds/ext-foundation.js">
</script>
<script src="https://rawgithub.com/torworx/exo/master/exo.js">
</script>
<script src="http://indigounited.com/dejavu/dejavu.js">
</script>
<script src="http://rawgithub.com/jayferd/pjs/v4.0.0/src/p.js"></script>
<script src="http://rawgithub.com/weikinhuang/Classify/v0.10.4/dist/classify.js"></script>
<script src="https://rawgithub.com/google/traceur-compiler/master/bin/traceur.js"></script>
<script src="http://raptorjs.org/dist/raptor.min.js" type="text/javascript"></script>
<script>
function inherit() {
    var len = arguments.length;
    var parent = (len > 1) ? arguments[0] : Function.constructor;
    var body = arguments[len - 1];
    body.prototype = parent.prototype;

    var t = function (){
        if (this.init)
            this.init.apply(this, arguments);
    };
    t.prototype = new body(parent.prototype);
    return t;
}
</script>
      
<script>
Benchmark.prototype.setup = function() {
    var __hasProp = {}.hasOwnProperty,
        __extends = function(child, parent) {
        for (var key in parent) {
          if (__hasProp.call(parent, key)) child[key] = parent[key];
        }
  
        function ctor() {
          this.constructor = child;
        }
        ctor.prototype = parent.prototype;
        child.prototype = new ctor();
        child.__super__ = parent.prototype;
        return child;
        };
  
    var JSFacePerson = jsface.Class({
      constructor: function(name) {
        this.name = name;
      },
      setAddress: function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      }
    });
  
    var JSFaceFrenchGuy = jsface.Class(JSFacePerson, {
      constructor: function(name) {
        JSFaceFrenchGuy.$super.call(this, name);
      },
      setAddress: function(city, street) {
        JSFaceFrenchGuy.$superp.setAddress.call(this, 'France', city, street);
      }
    });
  
    var JSFaceParisLover = jsface.Class(JSFaceFrenchGuy, {
      constructor: function(name) {
        JSFaceParisLover.$super.call(this, name);
      },
      setAddress: function(street) {
        JSFaceParisLover.$superp.setAddress.call(this, 'Paris', street);
      }
    });
  
  
  
    var MyPerson = my.Class({
      constructor: function(name) {
        this.name = name;
      },
      setAddress: function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      }
    });
  
    var MyFrenchGuy = my.Class(MyPerson, {
      constructor: function(name) {
        MyFrenchGuy.Super.call(this, name);
      },
      setAddress: function(city, street) {
        MyFrenchGuy.Super.prototype.setAddress.call(this, 'France', city, street);
      }
    });
  
    var MyParisLover = my.Class(MyFrenchGuy, {
      constructor: function(name) {
        MyParisLover.Super.call(this, name);
      },
      setAddress: function(street) {
        MyParisLover.Super.prototype.setAddress.call(this, 'Paris', street);
      }
    });
  
  
  
    var JRPerson = JRClass.extend({
      init: function(name) {
        this.name = name;
      },
      setAddress: function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      },
      sayHello: function() {
        console.log('I am ' + this.name + '. My address is ' + this.country + ', ' + this.city + ', ' + this.street + '.');
      }
    });
  
    var JRFrenchGuy = JRPerson.extend({
      init: function(name) {
        this._super(name);
      },
      setAddress: function(city, street) {
        this._super('France', city, street);
      }
    });
  
    var JRParisLover = JRFrenchGuy.extend({
      init: function(name) {
        this._super(name);
      },
      setAddress: function(street) {
        this._super('Paris', street);
      }
    });
  
  
  
    var EnderPerson = klass(function(name) {
      this.name = name;
    }).methods({
      setAddress: function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      }
    });
  
    var EnderFrenchGuy = EnderPerson.extend(function(name) {}).methods({
      setAddress: function(city, street) {
        this.supr('France', city, street);
      }
    });
  
    var EnderParisLover = EnderFrenchGuy.extend(function(name) {}).methods({
      setAddress: function(street) {
        this.supr('Paris', street);
      }
    });
  
  
  
    var ClassyPerson = Classy.$extend({
      __init__: function(name) {
        this.name = name;
      },
      setAddress: function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      }
    });
  
    var ClassyFrenchGuy = ClassyPerson.$extend({
      __init__: function(name) {
        this.$super(name);
      },
      setAddress: function(city, street) {
        this.$super('France', city, street);
      }
    });
  
    var ClassyParisLover = ClassyFrenchGuy.$extend({
      __init__: function(name) {
        this.$super(name);
      },
      setAddress: function(street) {
        this.$super('Paris', street);
      }
    });
  
  
  
    var PTClassPerson = PTClass.create({
      initialize: function(name) {
        this.name = name;
      },
      setAddress: function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      }
    });
  
    var PTClassFrenchGuy = PTClass.create(PTClassPerson, {
      initialize: function($super, name) {
        $super(name);
      },
      setAddress: function($super, city, street) {
        $super('France', city, street);
      }
    });
  
    var PTClassParisLover = PTClass.create(PTClassFrenchGuy, {
      initialize: function($super, name) {
        $super(name);
      },
      setAddress: function($super, street) {
        $super('Paris', street);
      }
    });
  
  
  
    var CoffeePerson = (function() {
  
      function CoffeePerson(name) {
        this.name = name;
      }
  
      CoffeePerson.prototype.setAddress = function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      };
  
      return CoffeePerson;
  
    })();
  
    var CoffeeFrenchGuy = (function(_super) {
  
      __extends(CoffeeFrenchGuy, _super);
  
      function CoffeeFrenchGuy(name) {
        CoffeeFrenchGuy.__super__.constructor.call(this, name);
      }
  
      CoffeeFrenchGuy.prototype.setAddress = function(city, street) {
        return CoffeeFrenchGuy.__super__.setAddress.call(this, "France", city, street);
      };
  
      return CoffeeFrenchGuy;
  
    })(CoffeePerson);
  
    var CoffeeParisLover = (function(_super) {
  
      __extends(CoffeeParisLover, _super);
  
      function CoffeeParisLover(name) {
        CoffeeParisLover.__super__.constructor.call(this, name);
      }
  
      CoffeeParisLover.prototype.setAddress = function(street) {
        return CoffeeParisLover.__super__.setAddress.call(this, "Paris", street);
      };
  
      return CoffeeParisLover;
  
    })(CoffeeFrenchGuy);
  
  
  
    Ext.define('ExtPerson', {
      constructor: function(name) {
        this.name = name;
      },
      setAddress: function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      }
    });
  
    Ext.define('ExtFrenchGuy', {
      extend: 'ExtPerson',
      constructor: function() {
        this.callParent(arguments);
      },
      setAddress: function(city, street) {
        this.callParent(['French', city, street]);
      }
    });
  
    Ext.define('ExtBeiJingLover', {
      extend: 'ExtFrenchGuy',
      constructor: function(name) {
        this.callParent(arguments);
      },
      setAddress: function(street) {
        this.callParent(['BeiJing', street]);
      }
    });
  
  
  
    var dejavuClassPerson = dejavu.Class.declare({
      initialize: function(name) {
        this.name = name;
      },
      setAddress: function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      }
    });
  
    var dejavuClassFrenchGuy = dejavu.Class.declare({
      $extends: dejavuClassPerson,
      initialize: function(name) {
        this.$super(name);
      },
      setAddress: function(city, street) {
        this.$super('France', city, street);
      }
    });
  
    var dejavuClassParisLover = dejavu.Class.declare({
      $extends: dejavuClassFrenchGuy,
      initialize: function(name) {
        this.$super(name);
      },
      setAddress: function(street) {
        this.$super('Paris', street);
      }
    });
  
  
  
    var dejavuClassPerson2 = dejavu.Class.declare({
      initialize: function(name){
        this.name = name;
      },
      setAddress: function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      }
    }, true);
  
    var dejavuClassFrenchGuy2 = dejavu.Class.declare({
      $extends: dejavuClassPerson2,
      initialize: function (name) {
        dejavuClassPerson2.call(this, name);
      },
      setAddress: function(city, street) {
        dejavuClassPerson2.prototype.setAddress.call(this, 'France', city, street);
      }
    }, true);
  
    var dejavuClassParisLover2 = dejavu.Class.declare({
      $extends: dejavuClassFrenchGuy2,
      initialize: function (name) {
        dejavuClassFrenchGuy2.call(this, name);
      },
      setAddress: function(street) {
        dejavuClassFrenchGuy2.prototype.setAddress.call(this, 'Paris', street);
      }
    }, true);
  
  
  
    var dejavuClassPerson3 = dejavu.Class.declare(function () {
      return {
            initialize: function(name){
                this.name = name;
            },
            setAddress: function(country, city, street) {
                this.country = country;
                this.city = city;
                this.street = street;
            }
        };
    }, true);
  
    var dejavuClassFrenchGuy3 = dejavuClassPerson3.extend(function ($super) {
      var initialize = $super.initialize;
      var setAddress = $super.setAddress;
      return {
          initialize: function(name){
              initialize.call(name);
          },
          setAddress: function(city, street) {
              setAddress.call(this, 'France', city, street);
          }
      };
    }, true);
  
    var dejavuClassParisLover3 = dejavuClassFrenchGuy3.extend(function ($super) {
      var initialize = $super.initialize;
      var setAddress = $super.setAddress;
      return {
          initialize: function(name){
              initialize.call(name);
          },
          setAddress: function(street) {
              setAddress.call(this, 'Paris', street);
          }
      };
    }, true);
  
  
  
    var ExoPerson = exo.define({
      constructor: function(name) {
        this.name = name;
      },
      setAddress: function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      }
    });
  
    var ExoFrenchGuy = exo.define({
      extend: ExoPerson,
      constructor: function(name) {
        ExoFrenchGuy.$superclass.call(this, name)
      },
      setAddress: function(city, street) {
        ExoFrenchGuy.$super.setAddress.call(this, 'French', city, street);
      }
    });
  
    var ExoParisLover = exo.define({
      extend: ExoFrenchGuy,
      constructor: function(name) {
        ExoParisLover.$superclass.call(this, name);
      },
      setAddress: function(street) {
        ExoParisLover.$super.setAddress.call(this, 'Paris', street);
      }
    });
  
    var ExoPerson2 = exo.extend(function() {
        return {
            constructor:function (name) {
                this.name = name;
            },
            setAddress:function (country, city, street) {
                this.country = country;
                this.city = city;
                this.street = street;
            }
        }
    });
  
    var ExoFrenchGuy2 = exo.extend(ExoPerson2, function($super) {
        return {
            setAddress:function (city, street) {
                $super.setAddress('French', city, street);
            }
        }
    });
  
    var ExoParisLover2 = exo.extend(ExoFrenchGuy2, function ($super) {
        return {
            setAddress:function (street) {
                $super.setAddress('Paris', street);
            }
        }
    });
  
    var AugmentPerson = Object.augment(function() {
      this.constructor = function (name) {
        this.name = name;
      };
  
      this.setAddress = function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      };
    });
  
    var AugmentFrenchGuy = AugmentPerson.augment(function(base) {
      var setAddress = base.setAddress;
  
      this.constructor = function (name) {
        AugmentPerson.call(this, name);
      };
  
      this.setAddress = function(city, street) {
        setAddress.call(this, "France", city, street);
      };
    });
  
    var AugmentParisLover = AugmentFrenchGuy.augment(function(base) {
      var setAddress = base.setAddress;
  
      this.constructor = function (name) {
        AugmentFrenchGuy.call(this, name);
      };
  
      this.setAddress = function(street) {
        setAddress.call(this, "Paris", street);
      };
    });
  
  
  
  
  
    var PPerson = P(function(proto) {
      proto.init = function (name) {
        this.name = name;
      };
  
      proto.setAddress = function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      };
    });
  
    var PFrenchGuy = P(PPerson, function(proto, person) {
      var setAddress = person.setAddress;
  
      proto.init = function (name) {
        PPerson.call(this, name);
      };
  
      proto.setAddress = function(city, street) {
        setAddress.call(this, "France", city, street);
      };
    });
  
    var PParisLover = P(PFrenchGuy, function(proto, frenchGuy) {
      var setAddress = frenchGuy.setAddress;
  
      proto.init = function (name) {
        PFrenchGuy.call(this, name);
      };
  
      proto.setAddress = function(street) {
        setAddress.call(this, "Paris", street);
      };
    });
  
  
  
    var ClassifyPerson = Classify({
      init: function (name) {
        this.name = name;
      },
  
      setAddress: function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      }
    });
    
    var ClassifyFrenchGuy = Classify(ClassifyPerson, {
      init: function (name) {
        this.parent(name);
      },
      setAddress: function(city, street) {
        this.parent("France", city, street);
      }
    });
  
    var ClassifyParisLover = Classify(ClassifyFrenchGuy, {
      init: function (name) {
        this.parent(name);
      },
      setAddress: function(street) {
        this.parent("Paris", street);
      }
    });
  
  
  
  
  var $__getDescriptors = function(object) {
    var descriptors = {}, name, names = Object.getOwnPropertyNames(object);
    for (var i = 0; i < names.length; i++) {
      var name = names[i];
      descriptors[name] = Object.getOwnPropertyDescriptor(object, name);
    }
    return descriptors;
  }, $__createClassNoExtends = function(object, staticObject) {
    var ctor = object.constructor;
    Object.defineProperty(object, 'constructor', {enumerable: false});
    ctor.prototype = object;
    Object.defineProperties(ctor, $__getDescriptors(staticObject));
    return ctor;
  }, $__superDescriptor = function(proto, name) {
    if (!proto) throw new TypeError('super is null');
    return Object.getPropertyDescriptor(proto, name);
  }, $__superCall = function(self, proto, name, args) {
    var descriptor = $__superDescriptor(proto, name);
    if (descriptor) {
      if ('value'in descriptor) return descriptor.value.apply(self, args);
      if (descriptor.get) return descriptor.get.call(self).apply(self, args);
    }
    throw new TypeError("Object has no method '" + name + "'.");
  }, $__getProtoParent = function(superClass) {
    if (typeof superClass === 'function') {
      var prototype = superClass.prototype;
      if (Object(prototype) === prototype || prototype === null) return superClass.prototype;
    }
    if (superClass === null) return null;
    throw new TypeError();
  }, $__createClass = function(object, staticObject, protoParent, superClass, hasConstructor) {
    var ctor = object.constructor;
    if (typeof superClass === 'function') ctor.__proto__ = superClass;
    if (!hasConstructor && protoParent === null) ctor = object.constructor = function() {};
    var descriptors = $__getDescriptors(object);
    descriptors.constructor.enumerable = false;
    ctor.prototype = Object.create(protoParent, descriptors);
    Object.defineProperties(ctor, $__getDescriptors(staticObject));
    return ctor;
  };
  
  
  
  
  
  
  
    var RaptorPerson = define.Class({
          init: function(name) {
              this.name = name;
          },
          setAddress: function(country, city, street) {
              this.country = country;
              this.city = city;
              this.street = street;
          }
      });
      var RaptorFrenchGuy = define.Class({superclass: RaptorPerson}, ['super'], function($super) {
          var superCtor = $super.constructor;
          var superSetAddress = $super.setAddress;
  
          function RaptorFrenchGuy(name) {
              superCtor.call(this, name);
          };
  
          RaptorFrenchGuy.prototype = {
              setAddress: function(city, street) {
                  superSetAddress.call(this, 'France', city, street);
              }
          }
  
          return RaptorFrenchGuy;
      });
  
      var RaptorParisLover = define.Class({superclass: RaptorFrenchGuy}, ['super'], function($super) {
          var superCtor = $super.constructor;
          var superSetAddress = $super.setAddress;
  
          function RaptorParisLover(name) {
              superCtor.call(this, name);
          };
  
          RaptorParisLover.prototype = {
              setAddress: function(street) {
                  superSetAddress.call(this, 'Paris', street);
              }
          }
  
          return RaptorParisLover;
      });
  
    var RingPerson = ring.create({
      init: function(name) {
        this.name = name;
      },
      setAddress: function(country, city, street) {
        this.country = country;
        this.city = city;
        this.street = street;
      }
    });
    var RingFrenchGuy = ring.create([RingPerson], {
      init: function(name) {
        this.$super(name);
      },
      setAddress: function(city, street) {
        this.$super('France', city, street);
      }
    });
  
    var RingParisLover = ring.create([RingFrenchGuy], {
      init: function(name) {
        this.$super(name);
      },
      setAddress: function(street) {
        this.$super('Paris', street);
      }
    });
  
  
  
  
  var InheritPerson = inherit(function () {
      this.init = function(name) {
          this.nome = name;
      }
      this.setAddress = function(country, city, street) {
            this.country = country;
            this.city = city;
            this.street = street;
      };
  });
  var InheritFrenchGuy = inherit(InheritPerson, function(base) {
      
          this.init = function (name) {
            base.init(name);
          };
      
          this.setAddress = function(city, street) {
            base.setAddress("France", city, street);
          };
  });
  var InheritParisLover = inherit(InheritFrenchGuy, function(base) {
      
      this.constructor = function (name) {
          base.init(name);
      };
      
      this.setAddress = function(street) {
          base.setAddress("Paris", street);
      };
  });

};
</script>

Preparation code output

Test runner

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

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
JSFace
var p3 = new JSFaceParisLover("Mary");
p3.setAddress("CH");
pending…
my.Class
var p6 = new MyParisLover("Mary");
p6.setAddress("CH");
pending…
John Resig Class
var p9 = new JRParisLover("Mary");
p9.setAddress("CH");
pending…
Klass
var p12 = new EnderParisLover("Mary");
p12.setAddress("CH");
pending…
Classy
var p15 = new ClassyParisLover("Mary");
p15.setAddress("CH");
pending…
PTClass
var p18 = new PTClassParisLover("Mary");
p18.setAddress("CH");
pending…
CoffeeScript Classes
var p21 = new CoffeeParisLover("Mary");
p21.setAddress("CH");
pending…
augment
var p24 = new AugmentParisLover("Mary");
p24.setAddress("CH");
pending…
Ext JS
var p27 = new ExtBeiJingLover("Mary");
p27.setAddress("CH");
pending…
dejavu
var p33 = new dejavuClassParisLover("Mary");
p33.setAddress("CH");
pending…
dejavu optimized
var p36 = new dejavuClassParisLover2("Mary");
p36.setAddress("CH");
pending…
dejavu optimized closures
var p39 = new dejavuClassParisLover3("Mary");
p39.setAddress("CH");
pending…
P
var p42 = new PParisLover("Mary");
p42.setAddress("CH");
pending…
Classifyjs
var p52 = new ClassifyParisLover("Mary");
p52.setAddress("CH");
pending…
Temoin
var p1000 = {};
p1000.name = "Mary";
p1000.city = "Paris";
p1000.address = "CH";
p1000.country = "France";
pending…
RaptorJS
var p70 = new RaptorParisLover("Mary");
p70.setAddress("CH");
pending…
exo
var p30 = new ExoParisLover("Mary");
p30.setAddress("CH");
pending…
exo closure
var p31 = new ExoParisLover2("Mary");
p31.setAddress("CH");
pending…
Ring.js
var p69 = new RingParisLover("Mary");
p69.setAddress("CH");
pending…
other way
var p70 = new InheritParisLover("Mary");
p70.setAddress("CH");
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.

0 Comments