optimizing prototype.js

Courtenay : June 8th, 2006

It seems like a lot of prototype and scriptaculous functions use Array#each, but this method uses a very slow way of iterating over the loop. Using an old-skool loop-unroll and other such optimziations from "faster duff device":http://www.websiteoptimization.com/speed/10/10-18.txt we get this faster method. If anyone has venkman and/or can benchmark this new method, please hit me up with some results! Preliminary tests indicate a 3x speedup.. (updated, bugfix)

Object.extend(Array.prototype, {
  _each: function(iterator) {
    var iter = 0;
    var len = this.length;
    var i = len % 8;
    if (i>0) do {
        iterator(this[iter++]);
      } while (--i);

    i = parseInt(len >> 3);
    if (i>0) do {
      iterator(this[iter++]);
      iterator(this[iter++]);
      iterator(this[iter++]);
      iterator(this[iter++]);
      iterator(this[iter++]);
      iterator(this[iter++]);
      iterator(this[iter++]);
      iterator(this[iter++]);
    } while (--i);

    //for (var i=0; i
You can test it with something like

[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18].each(function(i) { print(i) } );

8 Responses to “optimizing prototype.js”

  1. rick Says:
    I have a little "javascript benchmarking tool":http://svn.techno-weenie.net/projects/javascripts/benchmark/benchmark.js.
  2. rick Says:
    curse you, non-textiling comment form! link to benchmarking lib.
  3. runmen@yandex.ru Says:
    I test with that code, and in FF1.5 new _each slower, in IE6.0 improvement is 50 millisec for 100,000 loop arr = $R(0,100000).toArray(); d1 = new Date(); arr.each(function(i) { } ); d2 = new Date(); alert(d2-d1)
  4. madrobby Says:
    You can use the script.aculo.us unittest.js library for doing benchmarking, have a look at the test/unit/element_test.html file, included with the script.aculo.us distribution. You can do stuff like: benchmark(function(){ ...your code... },100,'Blabla'); which will run the function 100 times and report timing info.
  5. Bob Says:
    Regardless, prototype should be patched to remove the recalc of this.length in the for loop. Nice work.
  6. Georghios Says:

    Cool…

  7. Harrys Says:

    interesting

  8. Leo Says:

    Nice

Sorry, comments are closed for this article.