Javascript prototype operator performance: saves memory, but is it faster?

Viewed 24419

I read here (Douglas Crockford) using prototype operator to add methods to Javascript classes saves also memory.

Then I read in this John Resig's article "Instantiating a function with a bunch of prototype properties is very, very, fast", but is he talking about using prototype in the standard way, or is he talking about his specific example in his article?

For example, is creating this object:

function Class1()
{
   this.showMsg = function(string) { alert(string); }
}
var c = new Class1();
c.showMsg();

slower than creating this object, then?

function Class1() {}
Class1.prototype.showMsg = function(string) { alert(string); }
var c = new Class1();
c.showMsg();

P.S.

I know prototype is used to create inheritance and singleton object etc. But this question does not have anyhting to do with these subjects.


EDIT: to whom it might be interested also in performance comparison between a JS object and a JS static objet can read this answer below. Static object are definitely faster, obviously they can be usued only when you don't need more than one instance of the object.

10 Answers

Funny thing though. It depends not that much on which type of object you create and it matters how you write an example. Likewise i ran similar test as shmuel613 who wrote a similair test as Andrew. The first test is creating a single instance of a constructor, a class and an object literal and then measures the speed of execution from the constructor's instance functions, class's prototype methods and object literal's static functions:

var Y, Z, x, y, z;

class X {
    message(s) {
        var mymessage = s + "";
    };
    addition(i, j) {
        return (i * 2 + j * 2) / 2;
    };
};

Y = function () {
    this.message = function (s) {
        var mymessage = s + "";
    };
    this.addition = function (i, j) {
        return (i * 2 + j * 2) / 2;
    };
};

Z = {
    message(s) {
        var mymessage = s + "";
    },
    addition(i, j) {
        return (i * 2 + j * 2) / 2;
    }
}

function TestPerformance() {
    console.time("Closure time:");
    y = new Y(); // create a single instance
    for (var i = 0; i < 100000; i++) {
        // I am comparing a single instance with the other single instances
        y.message('hi');
        y.addition(i, 2);
    }
    console.timeEnd("Closure time:");

    console.time("Prototype time:");
    x = new X(); // create a single instance
    for (var i = 0; i < 100000; i++) {
        // I am comparing a single instance with the other single instances
        x.message('hi');
        x.addition(i, 2);
    }
    console.timeEnd("Prototype time:");

    console.time("Static object time:");
    for (var i = 0; i < 100000; i++) {
        z = Z; // obviously you don't really need this
        z.message('hi');
        z.addition(i, 2);
    }
    console.timeEnd("Static object time:");
}

TestPerformance();

The second test measures the speed of execution of creating many instances of a constructor, a class and object literals followed by executing the instance functions, prototype methods and static methods:

var Y, x, y, z;

class X {
    message(s) {
        var mymessage = s + "";
    };
    addition(i, j) {
        return (i * 2 + j * 2) / 2;
    };
};

Y = function () {
    this.message = function (s) {
        var mymessage = s + "";
    };
    this.addition = function (i, j) {
        return (i * 2 + j * 2) / 2;
    };
};

function TestPerformance() {
    console.time("Closure time:");
    //y = new Y()
    for (var i = 0; i < 100000; i++) {
        y = new Y(); // creating an instance
        y.message('hi');
        y.addition(i, 2);
    }
    console.timeEnd("Closure time:");

    console.time("Prototype time:");
    //x = new X();
    for (var i = 0; i < 100000; i++) {
        x = new X(); // creating an instance
        x.message('hi');
        x.addition(i, 2);
    }
    console.timeEnd("Prototype time:");

    console.time("Static object time:");
    for (var i = 0; i < 100000; i++) {
        z = { 
            message(s) {
                var mymessage = s + "";
            },
            addition(i, j) {
                return (i * 2 + j * 2) / 2;
            }
        }; // creating an instance such as from factory functions
        z.message('hi');
        z.addition(i, 2);
    }
    console.timeEnd("Static object time:");
}

TestPerformance();

The lesson learned is that DON'T blindly evolve a prejudice against something without being thorough. The execution speed from instance functions of a constructor (pre ES2016 classes) and the speed from prototype methods of a class are really just as fast as the execution speed from static functions of a object. However the creation speed followed by execution speed of a constructor instance with instance functions versus the creation speed of a class instance with prototype methods versus the creation speed of object literals with static methods shows rather that classes with prototype methods are faster created and executed on Chrome, Microsoft edge, and Opera. The creation speed of an object literal with static methods is only faster at Mozilla firefox

Related