Prototype vs Module pattern performance

JavaScript performance comparison

Revision 65 of this test case created by Jonathan Perry

Info

I have refactored these tests entirely.

Someone wrote the formulation:

for (var i=2000; i=0; i--) {

}

Possibly they did not notice that any statement contained by those curly braces will never execute. Paste the following into your JS console:

for (var i=2000; i=0; i--) { throw "An error"; }

You will never see the error "An error" thrown. "i=0" is falsy false. Presumably their intention was that this line should not execute; in which case, I can't see the point of it. Each test instantiated one object outside the "for" loop, regardless, but I think it's strange to include statements which do nothing.

Assuming that the object literal "objectLiteral" had been defined in the preparation or set-up code, someone had also written the statement:

a.push(new objectLiteral());

Because this statement appeared inside the curly braces of the never-executing "for" loop, a lurking error had never been thrown: "objectLiteral" is not a constructor.

I have refactored the object literal test to include the creation of the object literal; anything else does not seem to be a valid test of object creation. Every other test instantiates an object with "new"; pointing a variable at an object which has already been created outside of the test isn't the same thing, which will account for that test outperforming all of the other tests.

o = new ConstructedObject();

And

o = { };

Are as equivalent as can be, assuming only that the constructor "ConstructedObject" is defined outside the test, in the preparation code or set-up. If "objectLiteral" had been defined outside the test, similarly, then this following statement would not be equivalent to either of those above:

o = objectLiteral;

It simply assigns the existing object "objectLiteral" to variable "o".

Some tests use function declarations while others use function expressions. Again, these are not entirely equivalent but for the most part I haven't massaged those inequivalences away.

I have refactored all the methods to do something, and removed all references to the console within those methods, because that seems to be something too much. Since the never-executing "for" loop was duplicated within the test, the statements the duplicated loop contained were not executing, either: I have removed everything that they contained, and deleted the array "a" that was not being populated.

Preparation code

<script type="text/javascript">

function TraditionalPrototypeClass() { }
TraditionalPrototypeClass.prototype.foo = function () {
    return 'foo';
};
TraditionalPrototypeClass.prototype.bar = function () {
    return 'bar';
};

function TraditionalClass() {

    this.foo = function () {
        return 'foo';
    };
   
    this.bar = function () {
        return 'bar';
    };

}

var ModulePatternTraditionalPrototypeClass = (function () {
   
    function ModulePatternTraditionalPrototypeClass() { }
    ModulePatternTraditionalPrototypeClass.prototype.foo = function () {
        return 'foo';
    };
    ModulePatternTraditionalPrototypeClass.prototype.bar = function () {
        return 'bar';
    }    

    return ModulePatternTraditionalPrototypeClass;

}());

var ModulePatternTraditionalClass = (function () {

    function foo() {
        return 'foo';
    }
   
    function bar() {
        return 'bar';
    }
   
    return function () {
        this.foo = foo;
        this.bar = bar;
    };

}());

function FakeClass() {
   
    function __constructor() {
        this.init();
    }

    __constructor.prototype.init = function () { };

    __constructor.prototype.foo = function () {
        return 'foo';
    };
   
    __constructor.prototype.bar = function () {
        return 'bar';
    };

    return new __constructor();

}

function FakeClassWithoutInit() {
   
    function __constructor() { }

    __constructor.prototype.foo = function(){
        return 'foo';
    };
   
    __constructor.prototype.bar = function(){
        return 'bar';
    };

    return new __constructor();

}

</script>
<script>
Benchmark.prototype.setup = function() {
    var o;
};
</script>

Test runner

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

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
Traditional Prototypal Class
o = new TraditionalPrototypeClass();
pending…
Traditional Class
o = new TraditionalClass();
pending…
Object Literal
o = { 

  foo: function () {
       return 'a';
  },
  bar: function () {
    return 'b';
  }

};
pending…
Fake Class
o = new FakeClass();
pending…
Fake Class without init
o = new FakeClassWithoutInit();
pending…
Module Pattern Traditional Prototype Class
o = new ModulePatternTraditionalPrototypeClass();
pending…
Module Pattern Traditional Class
o = new ModulePatternTraditionalClass();
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