Inheritance Approaches

JavaScript performance comparison

Test case created by Lars Schultz

Preparation code


      
      <script>
Benchmark.prototype.setup = function() {
  var Homemade = {};
  Homemade.load = function(){
  	(function(){
  		var Class = Homemade.Vehicle = function(){};
  		var Object = Class.prototype;
  		
  		Class.counter = 0;
  		
  		Object.__construct = function(manufacturer){
  			this.id = ++Class.counter;
  			this.manufacturer = manufacturer;
  			this.components = new Array();
  			
  			this.driven = 0;
  			
  			return this;
  		};
  		
  		Object.getType = function(){
  			throw 'abstract';
  		};
  		
  		Object.drive = function(){
  			this.driven++;
  		};
  		
  		Object.addComponent = function(component){
  			this.components.push(component);
  		};
  		
  		Object.toString = function(){
  			return this.getType()
  				+'/'+ this.manufacturer
  				+' ('+ this.id +'/'+ this.driven +')'
  				+' ['+ this.components.join(', ') +']'
  			;
  		};
  	})();
  	
  	(function(){
  		var SuperClass = Homemade.Vehicle;
  		var SuperObject = SuperClass.prototype;
  		
  		var Class = Homemade.Truck = function(){};
  		var Object = Class.prototype = new SuperClass();
  		
  		Object.getType = function(){
  			return 'Truck';
  		};
  	})();
  	
  	(function(){
  		var SuperClass = Homemade.Vehicle;
  		var SuperObject = SuperClass.prototype;
  		
  		var Class = Homemade.Car = function(){};
  		var Object = Class.prototype = new SuperClass();
  		
  		Object.__construct = function(manufacturer,doors){
  			SuperObject.__construct.call(this,manufacturer);
  			
  			this.doors = doors;
  			
  			return this;
  		};
  		
  		Object.toString = function(){
  			return SuperObject.toString.call(this)
  				+ ' doors: '+ this.doors
  			;
  		};
  		
  		Object.getType = function(){
  			return 'Car';
  		};
  	})();
  	
  	(function(){
  		var SuperClass = Homemade.Car;
  		var SuperObject = SuperClass.prototype;
  		
  		var Class = Homemade.Car.Racing = function(){};
  		var Object = Class.prototype = new SuperClass();
  		
  		Object.__construct = function(manufacturer){
  			SuperObject.__construct.call(this,manufacturer,2);
  			
  			return this;
  		};
  		
  		Object.getType = function(){
  			return 'Racing Car';
  		};
  	})();
  	
  	(function(){
  		var Class = Homemade.Component = function(){};
  		var Object = Class.prototype;
  		
  		Object.__construct = function(name){
  			this.name = name;
  			
  			return this;
  		};
  		
  		Object.toString = function(){
  			return this.name;
  		};
  	})();
  };
  
  Homemade.instance = function(Class){
  	var instance = new Class();
  	
  	var args = new Array();
  	for( var i=1; i<arguments.length; i++){
  		args.push(arguments[i]);
  	}
  	
  	Class.prototype.__construct.apply(instance,args);
  	
  	return instance;
  };
  
  Homemade.test = function(){
  	var instance = Homemade.instance;
  	var Car = Homemade.Car;
  	var Truck = Homemade.Truck;
  	var Racing = Homemade.Car.Racing;
  	var Component = Homemade.Component;
  	
  	var fiat = instance(Car,'Fiat',4);
  	fiat.addComponent(instance(Component,'wheels'));
  	fiat.addComponent(instance(Component,'windows'));
  	
  	var scania = instance(Truck,'Scania');
  	scania.addComponent(instance(Component,'wheels'));
  	scania.addComponent(instance(Component,'boxes'));
  	
  	var ferrari = instance(Racing,'Ferrari');
  	
  	return [fiat,scania,ferrari];
  };
  
  var Mixed = {};
  Mixed.load = function(){
  	
  	Mixed.Vehicle = function(){
  		this.init = function(manufacturer){
  			this.id = ++Mixed.Vehicle.Counter;
  			this.manufacturer = manufacturer;
  			this.components = new Array();
  			
  			this.driven = 0;
  		};
  		
  		this.getType = function(){
  			throw 'abstract';
  		};
  		
  		this.drive = function(){
  			this.driven++;
  		};
  		
  		this.addComponent = function(component){
  			this.components.push(component);
  		};
  		
  		this.toString = function(){
  			return this.getType()
  				+'/'+ this.manufacturer
  				+' ('+ this.id +'/'+ this.driven +')'
  				+' ['+ this.components.join(', ') +']'
  			;
  		};
  	};
  	
  	Mixed.Vehicle.Counter = 0;
  	
  	
  	
  	
  	Mixed.Truck = function(){
  		this.getType = function(){
  			return 'Truck';
  		};
  	};
  	
  	Mixed.Truck.prototype = new Mixed.Vehicle;
  	
  	
  	
  	
  	Mixed.Car = function(){
  		this.vehicle_init = this.init;
  		this.vehicle_toString = this.toString;
  		
  		this.init = function(manufacturer,doors){
  			this.vehicle_init(manufacturer);
  			this.doors = doors;
  		};
  		
  		this.toString = function(){
  			return this.vehicle_toString() + ' doors: '+ this.doors ;
  		};
  		
  		this.getType = function(){
  			return 'Car';
  		};
  	};
  	
  	Mixed.Car.prototype = new Mixed.Vehicle;
  	
  	Mixed.Car.Racing = function(){
  		this.getType = function(){
  			return 'Racing Car';
  		};
  	};
  	
  	Mixed.Car.Racing.prototype = new Mixed.Car;
  		
  	Mixed.Component = function(){
  		this.init = function(name){
  			this.name = name;
  		};
  		
  		this.toString = function(){
  			return this.name;
  		};
  	};
  };
  
  Mixed.instance = function(Class){
  	var instance = new Class();
  	
  	var args = new Array();
  	for( var i=1; i<arguments.length; i++){
  		args.push(arguments[i]);
  	}
  	
  	instance.init.apply(instance,args);
  	
  	return instance;
  };
  
  Mixed.test = function(){
  	var instance = Mixed.instance;
  	var Car = Mixed.Car;
  	var Truck = Mixed.Truck;
  	var Racing = Mixed.Car.Racing;
  	var Component = Mixed.Component;
  	
  	var fiat = instance(Car,'Fiat',4);
  	fiat.addComponent(instance(Component,'wheels'));
  	fiat.addComponent(instance(Component,'windows'));
  	
  	var scania = instance(Truck,'Scania');
  	scania.addComponent(instance(Component,'wheels'));
  	scania.addComponent(instance(Component,'boxes'));
  	
  	var ferrari = instance(Racing,'Ferrari');
  	
  	return [fiat,scania,ferrari];
  };
  
  var Closure = {};
  Closure.load = function(){
  	Closure.Vehicle = function(){
  		var object = {};
  		
  		var id;
  		var manufacturer;
  		var components;
  		var driven;
  		
  		object.init = function (_manufacturer){
  			id = ++Closure.Vehicle.counter;
  			manufacturer = _manufacturer;
  			components = new Array();
  			
  			driven = 0;
  		};
  			
  		object.getType = function (){
  			throw 'abstract';
  		};
  			
  		object.drive = function (){
  			driven++;
  		};
  			
  		object.addComponent = function (component){
  			components.push(component);
  		};
  			
  		object.toString = function (){
  			return this.getType()
  				+'/'+ manufacturer
  				+' ('+ id +'/'+ driven +')'
  				+' ['+ components.join(', ') +']'
  			;
  		};
  		
  		return object;
  	};
  	
  	Closure.Vehicle.counter = 0;
  	
  	Closure.Truck = function(){
  		var object = Closure.Vehicle();
  		
  		object.getType = function(){
  			return 'Truck';
  		};
  		
  		return object;
  	};
  	
  	
  	
  	Closure.Car = function(){
  		var object = Closure.Vehicle();
  		
  		var Vehicle_init = object.init;
  		var Vehicle_toString = object.toString;
  		
  		var doors;
  		
  		object.init = function (manufacturer,_doors){
  			Vehicle_init.call(this,manufacturer);
  			
  			doors = _doors;
  		};
  		
  		object.getType = function (){
  			return 'Car';
  		};
  		
  		object.toString = function(){
  			return Vehicle_toString.call(this)
  				+ ' doors: '+ doors
  			;
  		};
  		
  		return object;
  	};
  	
  	
  	
  	Closure.Car.Racing = function(){
  		var object = Closure.Car();
  		
  		var Car_init = object.init;
  		
  		object.init = function (manufacturer){
  			Car_init.call(this,manufacturer,2);
  		};
  		
  		object.getType = function (){
  			return 'Racing Car';
  		};
  		
  		return object;
  	};
  	
  	
  	
  	Closure.Component = function(){
  		var object = {};
  		var name;
  		
  		object.init = function (_name){
  			name = _name;
  		};
  		
  		object.toString = function (){
  			return name;
  		};
  		
  		return object;
  	};
  };
  
  Closure.instance = function(Class){
  	var instance = Class();
  	
  	var args = new Array();
  	for( var i=1; i<arguments.length; i++){
  		args.push(arguments[i]);
  	}
  	
  	instance.init.apply(instance,args);
  	
  	return instance;
  };
  
  Closure.test = function(){
  	var instance = Closure.instance;
  	var Car = Closure.Car;
  	var Truck = Closure.Truck;
  	var Racing = Closure.Car.Racing;
  	var Component = Closure.Component;
  	
  	var fiat = instance(Car,'Fiat',4);
  	fiat.addComponent(instance(Component,'wheels'));
  	fiat.addComponent(instance(Component,'windows'));
  	
  	var scania = instance(Truck,'Scania');
  	scania.addComponent(instance(Component,'wheels'));
  	scania.addComponent(instance(Component,'boxes'));
  	
  	var ferrari = instance(Racing,'Ferrari');
  	
  	return [fiat,scania,ferrari];
  };
  
  var ObjectCreate = {};
  ObjectCreate.load = function(){
  	ObjectCreate.Vehicle = Object.create(Object.prototype,{
  		init : {value:function (manufacturer){
  			id = ++ObjectCreate.Vehicle.counter;
  			this.manufacturer = manufacturer;
  			this.components = new Array();
  			
  			this.driven = 0;
  			
  			return this;
  		}},
  		
  		getType : {value:function (){
  			throw 'abstract';
  		}},
  		
  		drive : {value:function (){
  			this.driven++;
  		}},
  		
  		addComponent : {value:function (component){
  			this.components.push(component);
  		}},
  		
  		toString : {value:function(){
  			return this.getType()
  				+'/'+ this.manufacturer
  				+' ('+ id +'/'+ this.driven +')'
  				+' ['+ this.components.join(', ') +']'
  			;
  		}}
  	});
  	
  	ObjectCreate.Vehicle.counter = 0;
  	
  	ObjectCreate.Truck = Object.create(ObjectCreate.Vehicle,{
  		getType : {value:function (){
  			return 'Truck';
  		}}
  	});
  	
  	ObjectCreate.Car = Object.create(ObjectCreate.Vehicle,{
  		init : {value:function(manufacturer,doors){
  			ObjectCreate.Vehicle.init.call(this,manufacturer);
  			
  			this.doors = doors;
  			
  			return this;
  		}},
  		
  		getType : {value:function (){
  			return 'Car';
  		}},
  		
  		toString : {value:function (){
  			return ObjectCreate.Vehicle.toString.call(this)
  				+ ' doors: '+ this.doors
  			;
  		}}
  	});
  	
  	ObjectCreate.Car.Racing = Object.create(ObjectCreate.Car,{
  		init : {value:function (manufacturer){
  			ObjectCreate.Car.init.call(this,manufacturer,2);
  			
  			return this;
  		}},
  		
  		getType : {value:function(){
  			return 'Racing Car';
  		}}
  	});
  	
  	ObjectCreate.Component = Object.create(Object.prototype,{
  		init : {value:function (name){
  			this.name = name;
  			
  			return this;
  		}},
  		
  		toString : {value:function (){
  			return this.name;
  		}}
  	});
  };
  
  ObjectCreate.instance = function(Class){
  	var instance = Object.create(Class);
  	
  	var args = new Array();
  	for( var i=1; i<arguments.length; i++){
  		args.push(arguments[i]);
  	}
  	
  	instance.init.apply(instance,args);
  	
  	return instance;
  };
  
  ObjectCreate.test = function(){
  	var instance = ObjectCreate.instance;
  	var Car = ObjectCreate.Car;
  	var Truck = ObjectCreate.Truck;
  	var Racing = ObjectCreate.Car.Racing;
  	var Component = ObjectCreate.Component;
  	
  	var fiat = instance(Car,'Fiat',4);
  	fiat.addComponent(instance(Component,'wheels'));
  	fiat.addComponent(instance(Component,'windows'));
  	
  	var scania = instance(Truck,'Scania');
  	scania.addComponent(instance(Component,'wheels'));
  	scania.addComponent(instance(Component,'boxes'));
  	
  	var ferrari = instance(Racing,'Ferrari');
  	
  	return [fiat,scania,ferrari];
  };
  
  //preload for runtime phases
  Homemade.load();
  Closure.load();
  Mixed.load();
  ObjectCreate.load();

};
</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
Homemade "definition"
Homemade.load();
pending…
Closure "definition"
Closure.load();
pending…
Mixed "definition"
Mixed.load();
pending…
ObjectCreate "definition"
ObjectCreate.load();
pending…
Homemade "runtime"
Homemade.test();
pending…
Closure "runtime"
Closure.test();
pending…
Mixed "runtime"
Mixed.test();
pending…
ObjectCreate "runtime"
ObjectCreate.test();
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