JavaScript Object Oriented Libraries Benchmark (v151)

Revision 151 of this benchmark created on


Description

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 HTML

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

Test runner

Ready to run.

Testing in
TestOps/sec
JSFace
var p3 = new JSFaceParisLover("Mary");
p3.setAddress("CH");
ready
my.Class
var p6 = new MyParisLover("Mary");
p6.setAddress("CH");
ready
John Resig Class
var p9 = new JRParisLover("Mary");
p9.setAddress("CH");
ready
Klass
var p12 = new EnderParisLover("Mary");
p12.setAddress("CH");
ready
Classy
var p15 = new ClassyParisLover("Mary");
p15.setAddress("CH");
ready
CoffeeScript Classes
var p21 = new CoffeeParisLover("Mary");
p21.setAddress("CH");
ready
augment
var p24 = new AugmentParisLover("Mary");
p24.setAddress("CH");
ready
Ext JS
var p27 = new ExtBeiJingLover("Mary");
p27.setAddress("CH");
ready
dejavu
var p33 = new dejavuClassParisLover("Mary");
p33.setAddress("CH");
ready
dejavu optimized closures
var p39 = new dejavuClassParisLover3("Mary");
p39.setAddress("CH");
ready
P
var p42 = new PParisLover("Mary");
p42.setAddress("CH");
ready
Classifyjs
var p52 = new ClassifyParisLover("Mary");
p52.setAddress("CH");
ready
Temoin
var p1000 = {};
p1000.name = "Mary";
p1000.city = "Paris";
p1000.address = "CH";
p1000.country = "France";
ready
RaptorJS
var p70 = new RaptorParisLover("Mary");
p70.setAddress("CH");
ready
exo
var p30 = new ExoParisLover("Mary");
p30.setAddress("CH");
ready
exo closure
var p31 = new ExoParisLover2("Mary");
p31.setAddress("CH");
ready
Ring.js
var p69 = new RingParisLover("Mary");
p69.setAddress("CH");
ready

Revisions

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