Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript Prototype vs General Functions - Performance/Readability

So I wrote these tests to see how much faster using prototypes would be...

function User() {
    return {
        name: "Dave",
        setName: function(n) {
            this.name = n;
        },
        getName: function() {
            return this.name;
        }
    };
}

function UserPrototype() {
    if (!(this instanceof UserPrototype)) return new UserPrototype();
    this.name = "Dave";
}
UserPrototype.prototype.getName = function() {
    return this.name;
};
UserPrototype.prototype.setName = function(n) {
    this.name = n;
};

function setName(obj,name)
{
    obj.name = name;
}
function getName(obj)
{
    return obj.name;
}

//Test 1
var c = 10000000;
var tstart = 0;
var tend = 0;
tstart = new Date().getTime();
for (var j = 0; j < c; j++) {
    var newUser = User();
    newUser.setName("michael");
    newUser.getName();
}
tend = new Date().getTime() - tstart;
console.log("Returning object with methods: " + tend / 1000.0 + " seconds");
//Test 2
tstart = new Date().getTime();
for (var j = 0; j < c; j++) {
    var newUser = new UserPrototype();
    newUser.setName("michael");
    newUser.getName();
}
tend = new Date().getTime() - tstart;
console.log("Using prototypes: " + tend / 1000.0 + " seconds");
//Test 3
tstart = new Date().getTime();
for (var j = 0; j < c; j++) {
    var newUser = {name:"dave"};
    setName(newUser,"michael");
    getName(newUser);
}
tend = new Date().getTime() - tstart;
console.log("Using general functions: " + tend / 1000.0 + " seconds");
​

My results:

Returning object with methods: 9.075 seconds
Using prototypes: 0.149 seconds 
Using general functions: 0.099 seconds 

I wrote the first two tests and when I saw the results I thought about why I was seeing them... I'm thinking the reason is that the object returning is slow due to the fact that two new method property instances are created every time the object is instantiated while the prototype method is faster because it just creates the function once. The closeness of performance between general function calls and prototypes makes me think I'm right about my assumption.

So my first question is, am I right about my assumption?

My second question is, how can I make writing with prototypes more readable but with keeping the high performance? Is there a way to code prototypes in a way that would look like they are in a "class" (if that makes sense)

*EDIT - I forgot to do a test with Object.create(), just did one and posted results. JSFiddle: (http://jsfiddle.net/k2xl/SLVLx/).

I get now :

Returning object with methods: 0.135 seconds fiddle.jshell.net:63
Using prototypes: 0.003 seconds fiddle.jshell.net:72
Using general functions: 0.002 seconds fiddle.jshell.net:81
Returning object.create version: 0.024 seconds 

Looks like this might be the solution?

like image 412
K2xL Avatar asked Sep 02 '12 17:09

K2xL


1 Answers

I agree with your assumption. This is also bourn out if the code is written like this:

function UserObject() {
    this.name = "Dave";

    this.getName = function() {
        return this.name;
    };
    this.setName = function(n) {
        this.name = n;
    };
}

In this case, like in your "object" method, the getName and setName methods are created every time a UserObject object is constructed.

There are slight differences in your code between the "prototypes" and "functions" methods. Removing if (!(this instanceof UserPrototype)) return new UserPrototype(); (which is an unnecessary safe guard) shaves quite a bit off. Arguably too, a closer comparasion to ...

var newUser = new UserPrototype();
[newUser].name = "Dave";

... is ...

var newUser = new Object();
newUser.name = "dave";

... because ...

var newUser = {name:"dave"};

... rides high on native code when creating the Object and adding the name property.

In that case, the results flip and the "prototypes" methods comes out faster. See a jsFiddle here:

  • http://jsfiddle.net/bcfPp/2/

About how to make your prototypes more readable, I can't help. To me, they are readable :-)

like image 155
Oliver Moran Avatar answered Sep 24 '22 13:09

Oliver Moran