Freigeben über


Javascript prototype versus closure execution speed

When Javascript execution speed matters consider using prototype instead of closures where possible. Even for a small closure the difference can be noticable when called hundreds of times. Consider the following example that implements a Pixel object with some ancillary functions in both the closure and prototype patterns:

// Closure implementation

function Pixel(x, y)

{

  this.x = x;

  this.y = y;

  this.getX = function()

  {

    return this.x;

  }

  this.getY = function()

  {

    return this.y;

  }

  this.setX = function(value)

  {

    this.x = value;

  }

  this.setY = function(value)

  {

    this.y = value;

  }

}

 

// Prototype implementation

function PixelP(x, y)

{

  this.x = x;

  this.y = y;

}

PixelP.prototype.getX = function()

{

  return this.x;

}

PixelP.prototype.getY = function()

{

  return this.y;

}

PixelP.prototype.setX = function(value)

{

  this.x = value;

}

PixelP.prototype.setY = function(value)

{

  this.y = value;

}

 

 

function TestPerformance()

{

  var closureStartDateTime = new Date();

  for (var i = 0; i < 20000; i++)

  {

    var x = new Pixel(i, i);   

  }

  var closureEndDateTime = new Date();

 

  var prototypeStartDateTime = new Date();

  for (var i = 0; i < 20000; i++)

  {

    var x = new PixelP(i, i);   

  }

  var prototypeEndDateTime = new Date();

  var closureTime = closureEndDateTime.getTime() - closureStartDateTime.getTime();

  var prototypeTime = prototypeEndDateTime.getTime() - prototypeStartDateTime.getTime();

  alert("Closure time: " + closureTime + ", prototype time: " + prototypeTime);

}

 

When this is run in IE7 on my machine, the closure implementation takes around 450ms and prototype takes around 140ms. Add two more empty functions and the closure time increases to 560ms and prototype to 155ms.

On Firefox 1.5.0.9 the difference is in the listed example is even larger with the closure taking 515ms and prototype still around 140ms.

For small applications that don't construct hundreds or thousands of the same type of object the execution speed difference between closure and prototype probably doesn't matter so as with all performance advice measure, measure, measure.

Comments

  • Anonymous
    February 13, 2007
    Here is what I got on my machine IE 7.0.5730.11 Closure time: 438, prototype time: 109 Firefox 2.0.0.1 Closure time: 218, prototype time: 63

  • Anonymous
    July 03, 2007
    I think it's not closures vs. prototypes, so much as its a function that allocates four function objects versus a function that doesn't.  Object allocation time completely dominates this test.  Function invocation should be in the tens to hundreds of cycles per, not thousands or tens of thousands. To test closure invocation vs. prototype invocation, you'd need to reuse the Pixel object, or at least its member functions.

  • Anonymous
    July 03, 2007
    Right. The whole point of prototypes is that it takes care of assigning member functions for you. In this case the Pixel object cannot be reused and if you're going to simulate prototype by reusing the member functions then why not use prototype in the first place? In my example I deliberately used this to reference variables to eliminate any code difference between the two to get just the difference between the two ways of implementing an object; a true closure implementation would have used private variables which cannot be shared across Pixel objects since they would have their own private variables.