JavaScript Object Oriented Libraries Benchmark

JavaScript performance comparison

Revision 175 of this test case created by Naja Melan

Preparation code

<script src="https://rawgithub.com/nicolas-van/ring.js/master/underscore.js" type="text/javascript"></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://github.com/javascript/augment/raw/master/augment.js">
</script>
<script src="https://rawgithub.com/torworx/exo/master/exo.js">
</script>
<script src="https://github.com/IndigoUnited/js-dejavu/raw/master/dist/regular/strict/dejavu.js">
</script>
<script src="https://rawgithub.com/jayferd/pjs/master/src/p.js"></script>
<script src="https://rawgithub.com/weikinhuang/Classify/master/dist/classify.js"></script>
<script src="https://rawgithub.com/google/traceur-compiler/master/bin/traceur.js"></script>
<script src="https://github.com/najamelan/TidBits_Javascript_OoJs/raw/master/oojs.js" type="text/javascript"></script>


      
<script>
Benchmark.prototype.setup = function() {
  // JSFace library
  //
  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);
    }
  });
  
  
  
  // My library
  //
  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);
    }
  });
  
  
  
  
  // JR Library
  //
  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);
    }
  });
  
  
  
  // Ender Library
  //
  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);
    }
  });
  
  
  
  // Classy Library
  //
  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);
    }
  });
  
  
  
  // PTClass library
  //
  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);
    }
  });
  
  
  
  // Coffee Library
  //
  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 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);
  
  
  // dejavuClass library
  //
  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);
  
  
  
  // Exo Library
  //
  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);
    }
  });
  // warm up
  new ExoPerson();
  new ExoFrenchGuy();
  new ExoParisLover();
  
  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);
          }
      }
  });
  // warm up
  new ExoPerson2();
  new ExoFrenchGuy2();
  new ExoParisLover2();
  
  
  // Augment library
  //
  var AugmentPerson = augment(Object, 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 = augment(AugmentPerson, 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 = augment(AugmentFrenchGuy, function(base) {
    var setAddress = base.setAddress;
  
    this.constructor = function (name) {
      AugmentFrenchGuy.call(this, name);
    };
  
    this.setAddress = function(street) {
      setAddress.call(this, "Paris", street);
    };
  });
  
  
  
  
  // P Library
  //
  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);
    };
  });
  
  
  
  // Classify library
  //
  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);
    }
  });
  
  
  
  // TidBits OoJs
  // https://github.com/najamelan/TidBits_Javascript_OoJs
  //
  ;( function class_OoJsPerson( namespace )
  {

      'use strict';
  
      if( namespace[ "OoJsPerson" ] ) return    // protect against double inclusions
  
          namespace.OoJsPerson = OoJsPerson
      var Static               = TidBits.OoJs.setupClass( namespace, "OoJsPerson" )
  
  
      Static.Public()
  
  
      // constructor
      //
      function OoJsPerson( name )
      {
          this.name    = name
          this.country = null
          this.city    = null
          this.street  = null
  
  
          return this.Public
          (
                "name"
              , "country"
              , "city"
              , "street"
  
              , setAddress
          )
      }
  
  
      function setAddress( country, city, street )
      {
        this.country = country
        this.city    = city
        this.street  = street
      }
  
  })( this )
  
  
  
  ;( function class_OoJsFrenchGuy( namespace )
  {

      'use strict';
  
      if( namespace[ "OoJsFrenchGuy" ] ) return    // protect against double inclusions
  
          namespace[ "OoJsFrenchGuy" ] = OoJsFrenchGuy
      var Static = TidBits.OoJs.setupClass( namespace, "OoJsFrenchGuy", { inherit: "OoJsPerson", as: "public" } )
  
  
      Static.Public()
  
  
      // constructor
      //
      function OoJsFrenchGuy( name )
      {
          this.Super( name )
  
          return this.Public( setAddress )
      }
  
  
      function setAddress( city, street )
      {
        this.OoJsPerson.setAddress( "France", city, street )
      }
  
  })( this )
  
  
  
  ;( function class_OoJsParisLover( namespace )
  {

      'use strict';
  
      if( namespace[ "OoJsParisLover" ] ) return    // protect against double inclusions
  
          namespace[ "OoJsParisLover" ] = OoJsParisLover
      var Static = TidBits.OoJs.setupClass( namespace, "OoJsParisLover", { inherit: "OoJsFrenchGuy", as: "public" } )
  
  
      Static.Public()
  
  
      // constructor
      //
      function OoJsParisLover( name )
      {
          this.Super( name )
  
          return this.Public( setAddress )
      }
  
  
      function setAddress( street )
      {
        this.OoJsFrenchGuy.setAddress( "France", "Paris", street )
      }
  
  })( this )
  
  
  
  // ??? library?
  //
  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;
  };
  
  
  
  
  
  
  

};
</script>

Preparation code output

<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://github.com/javascript/augment/raw/master/augment.js"> </script> <script src="https://rawgithub.com/torworx/exo/master/exo.js"> </script> <script src="https://github.com/IndigoUnited/js-dejavu/raw/master/dist/regular/strict/dejavu.js"> </script> <script src="https://rawgithub.com/jayferd/pjs/master/src/p.js"></script> <script src="https://rawgithub.com/weikinhuang/Classify/master/dist/classify.js"></script> <script src="https://rawgithub.com/google/traceur-compiler/master/bin/traceur.js"></script> <script src="https://github.com/najamelan/TidBits_Javascript_OoJs/raw/master/oojs.js" type="text/javascript"></script>

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…
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…
exo
var p30 = new ExoParisLover("Mary");
p30.setAddress("CH");
pending…
exo closure
var p31 = new ExoParisLover2("Mary");
p31.setAddress("CH");
pending…
TidBits OoJs
var oojs = new this.OoJsParisLover( "Mary" )
oojs.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