JavaScript Object Oriented Libraries Benchmark

JavaScript performance comparison

Revision 151 of this test case created

Info

Benchmark multiple classes systems.

-- Pushing on the top previous version of this test because someone pushed versions where the creation of the classes is located inside the tests. This has little to no interest because classes are generally created just after the loading of the application and not during the execution. The purpose of this benchmark is to compare additional operations performed by class systems during the execution (creation and usage of objects).

Preparation code

<script src="https://rawgithub.com/jashkenas/underscore/1.5.2/underscore.js"></script>
<script src="https://rawgithub.com/nicolas-van/ring.js/1.0.0/ring.js"></script>
<script src="https://rawgithub.com/tnhu/jsface/v2.1.1/jsface.js"></script>
<script src="https://rawgithub.com/jiem/my-class/25e7718fe88833a77149d2ca250778d3539e9ef7/my.class.js"></script>
<script src="https://rawgithub.com/ded/klass/v1.0/klass.js"></script>
<script src="https://rawgithub.com/mitsuhiko/classy/1.4/classy.js"></script>
<script>
window.Classy = Class.$noConflict();
</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/736efa72fbd9ff5be198e4dde63957a298b18c40/exo.js"></script>
<script src="https://rawgithub.com/IndigoUnited/dejavu/0.4.4/dist/regular/loose/dejavu.js"></script>
<script src="https://rawgithub.com/jayferd/pjs/v4.0.0/src/p.js"></script>
<script src="https://rawgithub.com/weikinhuang/Classify/v0.10.4/dist/classify.js"></script>
<script src="https://rawgithub.com/raptorjs/raptorjs/v2.5.4/lib/raptor/raptor.js" type="text/javascript"></script>
<script src="https://rawgithub.com/bclinkinbeard/Class.js/v1.0.0/Class.js"></script>

<script>
  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;
      };
</script>
<script>
  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);
    }
  });

</script>
<script>

  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);
    }
  });

</script>
<script>
  var JRPerson = Class.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);
    }
  });


</script>
<script>

  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);
    }
  });


</script>
<script>

  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);
    }
  });


</script>
<script>

  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);


</script>
<script>

  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]);
    }
  });


</script>
<script>

  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);
    }
  });


</script>
<script>

  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);


</script>
<script>

  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 test = new ExoParisLover("Mary");
  test.setAddress("CH");
  if (test.name !== "Mary") throw new Error();
  if (test.city !== "Paris") throw new Error();
  if (test.street !== "CH") throw new Error();
  if (test.country !== "French") throw new Error();

</script>
<script>

  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);
          }
      }
  });


</script>
<script>

  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);
    };
  });


</script>
<script>

  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);
    };
  });


</script>
<script>

  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);
    }
  });


</script>
<script>

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>
<script>

  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;
    });


</script>
<script>

  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);
    }
  });


</script>
 

Preparation code output

Test runner

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

Java applet disabled.

Testing in unknown unknown
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…
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 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…

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. Here’s a list of current revisions for this page:

0 comments

Add a comment