views:

116

answers:

3

Has anybody done benchmarking, or can link to an article on this subject? Particularly interested in IE results, since usually JS performance is not a problem in other browsers.

I would like to know how much slower it is to do something like:

var numbers = [1, 2, 3, 4, 5, 6, 7];
var results = numbers.map(function() { 
  // do some stuff
});

instead of the typical:

var numbers = [1, 2, 3, 4, 5, 6, 7];
var results = [];

for (var i = 0; i < numbers.length; i++) {
  var number = numbers[i];
  var result;
  // do some stuff
  results.push(result);
}

I obviously prefer the functional style, but I assume the extra overhead of calling an extra function for each item could slow things down with big collections.

Thanks!

+2  A: 

This one is really interesting:

http://www.slideshare.net/madrobby/extreme-javascript-performance

However, in ECMAScript5-ready JS engines with native Array.map(), things may change drastically.

Pumbaa80
Well.. looks like slide 18 pretty much answers this question :(
Infinity
+3  A: 

Not content with the lack of proof on this subject, I wrote a short benchmark. It's far from perfect but I think it answers the question.

I ran it in IE 8/win, and while the functional method is slower, it's never going to be the bottleneck in real code. (Unless you're doing stuff that you shouldn't be doing in the client anyway)

So I will be using the cleaner approach whenever I have to pick (yay)

(Best of 5)
Functional method: 453ms
Old school approach: 156ms

Array.prototype.map = function(fun) {
  var len = this.length >>> 0;
  if (typeof fun != "function")
    throw new TypeError();

  var res = new Array(len);
  var thisp = arguments[1];
  for (var i = 0; i < len; i++) {
    if (i in this)
      res[i] = fun.call(thisp, this[i], i, this);
  }

  return res;
};

/**
 *
 *
 */

// Initialize test array
var numbers = [];
for (var i = 0; i < 100000; i++) numbers.push(i);

// Benchmark!
var start = +new Date();

// Test 1
var results1 = numbers.map(function(num) {
  return num + num;
});

alert('1. Functional map:' + (start - new Date()));
start = +new Date();

// Test 2
var results2 = [];
for (var j = 0, l = numbers.length; j < l; j++) {
  var num = numbers[j];
  results2.push(num + num)
}

alert('1. Old school approach' + (start - new Date()));
start = +new Date();
Infinity
+1  A: 

This is very interesting too:

http://documentcloud.github.com/underscore/test/test.html

The results vary from browser to browser, because underscore tries to use the native alternative where available.

Sebastián Grignoli