Classes are useful constructs in Object-Oriented Programming because they are capable of producing a fleet of similar instances conforming to some interface.

JavaScript does not have classes in the same way that other Object-Oriented languages posess them. In JavaScript, there are four main class-like constructs: functional, extended-functional, prototypal, pseudoclassical.

We won't go into the differences here between them all but will focus on the prototypal and pseudoclassical since they are the most used in JavaScript. I had read that the pseudoclassical instantiation method was the preferred method by many and that some browsers had been optimized for this method in terms of speed.

The impetus for this post was a curiosity to find out if I could test how much faster the pseudoclassical method was if at all. In order to  do that, I will explain a method for testing the instantiation speed.

Setting up a Speed Test

The following speed test is modified from a speed test presented in a Code School Course called JavaScript Best Practices Part 2. In order to test the speed of instantiation with both of these methods, we envision a class called Computer that when instantiated, will create... yes, Computers. There is nothing special about this computer. It will create Computers with default properties of memory ("16 GB"), speed ("2.1 Gz"), and a random color that will be passed in at the time of instantiation.

The Prototypal class looks like this

var Computer = function(color) {
  var someInstance = Object.create(computerMethods);
  someInstance.memory = "16 GB";
  someInstance.speed = "2.1 GHz";
  someInstance.color = color;
  return someInstance;
};

The Pseudoclassical class looks like this

var Computer = function(color) {
  this.memory = "16 GB";
  this.speed = "2.1 GHz";
  this.color = color;
};

You will note off the bat here if you aren't already familiar with the difference between these two class-like ways of creating similar objects is that the Prototypal method has two extra lines of code to create an object and return that object at the end of the function. With the Pseudoclassical method, these two lines aren't necessary because when a new object is instantiated from this constructor function with the keyword new, the JavaScript engine will automatically take care of creating and returning the object for us.

The Speed Test Function

Now, we set up a SpeedTest class that will accept the function being tested, parameters passed in, and number of repetitions to perform the speed test. It looks like this:

var SpeedTest = function(testImplement, testParams, repetitions){
  this.testImplement = testImplement;
  this.testParams = testParams;
  this.repetitions = repetitions || 10000;
  this.average = 0;
};

SpeedTest.prototype.startTest = function() {
    var beginTime, endTime, testTime;
    var holderArray = [];
    for ( var i = 0, x = this.repetitions; i < x; i++ ) {
      beginTime = +window.performance.now();
      this.testImplement( this.testParams );
      endTime = +window.performance.now();
      testTime = endTime - beginTime;
      holderArray.push(testTime);
     }
    this.average = average(holderArray);
    this.stdDev = standardDeviation(holderArray);
    return console.log("Average execution time across " + this.repetitions +
        ": " + this.average + " Standard Dev :" + this.stdDev);
};

The Speed Test above goes beyond the speed test implemented in the Code School course. This test adds a test for standard deviation of the repetitive speed tests. If you need a refresher on standard deviation you can read more here on Wikipedia, but it basically tests for the deviation or variance in a set of data. So, if I'm looking for an average value here, as I am for the speed test, I want to know how tight my data is meaning how close together are my values. If there is a large spread, I'll be less likely to trust my conclusion that one class-like method is better than another.

In brief, we first create the Speed Test constructor function parameters of the function we want to test (testImplement), any arguments the function we are testing takes (testParams), and the number of repetitions. We then extend the constructor by adding the startTest method to it's prototype in the Pseudoclassical style. When the startTest method is called, it finds the time before the constructor function (either Prototypal or Pseudoclassical) is executed and the time after, the difference between these two times, the average of those differences across a pre-defined number of repetitions of the test, and then finds the standard deviation of the values from the average. If the window.performance.now() is new to you, it was new to me too. Apparently, this call is similar to new Date() which gets the current date and time to the millisecond but is more accurate, according to the Mozilla Developer Network, to the microsecond. I'll explain later why this was important.

Executing the Speed Test

The next thing to do is to instantiate the speed test to a new variable and then run the speed test.

var speedTest = new SpeedTest(createObject, randomColor, 100000);
speedTest.startTest();

The last bit of code to share is the createObject function which will instantiate our desired object using either the Prototypal of the Pseudoclassical pattern.

var createObject = function(color) {
  var laptop = new Computer(color);
  laptop.startup();
};

Note that the above is for the Pseudoclassical pattern. When testing the Prototypal pattern, I simply removed the new keyword before Computer.

And, the code for passing in a random color:

var colors = ["red", "blue", "green", "silver", "orange"];
var randomColor = colors[Math.floor(Math.random() * 5 )];

In order to test all of the code above, I referenced my JavaScript file in a blank HTML document and checked my console.log output for the average time and standard deviation. I used 100,000 repetitions.

Initially, my results were confusing. The standard deviation was much larger than the average and I kept thinking "how is this possible". And this highlights the need to check variance in your test data. It turns out from my tests that the average execution time for my tests were under a millisecond. But originally, when I was using new Date() to get a timestamp, I wasn't aware I'd need accuracy of better than a millisecond. new Date() is only accurate to the millisecond but I would never have known the importance of this if I'd just trusted my average speed test value across 100,000 repetitions. Because the standard deviation value was so high, I looked at what was in my holderArray of data and found that a lot of the values were 0. In other words, my startTime and endTime were coming out to the same value. Huhhhhh, i thought. The average value looked legit but then I realized that a few 1's strewn across my holderArray would hide all the 0's in the average if I hadn't been looking a little deeper. So, I did a little research and stumbled on the window.performance.now() method previously mentioned which has down to the microsecond accuracy. I really only needed tenths of a millisecond accuracy so I figured I was set. I used that and then looked at my holderArray. Now I saw a lot of decimal data but no more 0's.

What I discovered surprised me. The results are shown below in a table with the average speed for creating an object using one of the two patterns along with the standard deviation.

     Pattern    Average Speed (ms)    Standard Deviation (ms)        Pseudoclassical    0.0007    0.0027        Prototyal    0.0010    0.0032  

What we see is that instantiation of these objects using one of the two patterns takes around 1 microsecond and that we are actually at the limit of our test capability. Actually, since we are at the limit, the time might be faster than 1 microsecond but given the tools at hand, namely the browser, I am unable to test to a finer resolution than 1 microsecond. The fact that the standard deviation is larger than the average points to the fact that we are beyond the limit of our test ability.

Conclusion

The above method for testing the speed of creating an object based on either the Prototypal JavaScript class pattern or the Pseudoclassical JavaScript pattern demonstrated that unless one is building an app that has many many many object instantiations from a class, the time it takes to create the object is insignificant and one should not select the Pseudoclassical pattern just on the premise of speed. The data does suggest that it is slightly faster but with such high standard deviations the data is hardly reliable to conclusively show a speed winner.

This speed test can be used to test other function speed and indeed, in tests where I put a loop in the object instantiation, the average time was on the millisecond time scale with standard deviation numbers that showed far less variance. Feel free to use this speed test to test different variations of a function you have written.