Re: Copying DOM NodeLists to genuine JS Arrays - Performance

Jonathan Hurshman <[email protected]> Wed, 8 Mar 2006 06:36:27 -0800 (PST)
Newsgroups gmane.comp.web.dom.wdf
Message-ID <[email protected]>
I don't know what browser you're testing with or what kind of machine,
but here's what I found:

I tested with Firefox 1.0.7 and IE 6.0 on a dog-slow Windows XP test
machine (256 MB RAM, 542 MHz CPU), and with Firefox 1.5 and Safari 2.0
on my dev machine (4.5 GB RAM, 2x2.0 G5, OS X 10.4.5).

The page contained 7000 DIVs interspersed with 14000 other nodes which
were not iterated.

I tested 4 algorithms:

Algorithm 1:
      for (var i = 0; i < nodes.length; i++) {
        arr.push(nodes[i]);
      }

Algorithm 2 (this is pretty much your initial algorithm):
      var len = nodes.length;
      for (var i = 0; i < len; i++) {
        arr.push(nodes[i]);
      }

Algorithm 3:
Your 64-wide modified Duff's Device

Here are the results I saw:

WinXP, FF 1.0.7
Algorithm 1: 1200ms
Algorithm 2: 750ms
Algorithm 3: 650ms

WinXP, IE 6.0
Algorithm 1: 19000ms (no typo, this took 19 seconds)
Algorithm 2: 1200ms
Algorithm 3: 920ms

OS X, FF 1.5
Algorithm 1: 350ms
Algorithm 2: 270ms
Algorithm 3: 51ms

OS X, Safari 2.0
Algorithm 1: 611ms
Algorithm 2: 40ms
Algorithm 3: 14000ms (yes, 14 seconds!)

(I don't know why Duff's Device performs so incredibly badly in Safari,
given that Safari totally kicks butt on a standard loop algorithm like
#2.)

My overall observation is that I do not see the significant improvement
you saw in moving from algorithm 2 to algorithm 3, except in the case
of Firefox 1.5.

- Jonathan Hurshman

--- Chris <[email protected]> wrote:

> Hi all,
> 
> I'm currently working on a script that executes over 7000 tags, in
> about 
> 7 seconds.
> 
> I analyzed it and determined that the slowest operation was this:
> 
> var length = tagsBase.length;
> for(var i = 0; i < length; i++)
>     tags.push(tagsBase[i]);
> 
> In other words, simply copying a DOM NodeList (fetched by 
> .getElementsByTagName()) to a legit array.
> 
> It took over 4 seconds of the 7 second execution time. Another 2
> seconds 
> was spent performing a similar operation (with a filter applied).
> 
> 
> The solution I applied to optimize it uses Duff's Device:
> http://home.earthlink.net/~kendrasg/info/js_opt/jsOptMain.html
> (bottom of that page)
> 
> I used a 64-wide version of the Modified version - here's a code
> snippet:
> 
> Array.appendNodeList64(array, tags) {
>     // Modified Duff's Device (Tom Duff, Kendra SG, Anon)
>     var iterations = tags.length;
>     var iTags = iterations - 1;
>     var i = iTags + array.length;
> 
>     var n = iterations % 64;
>     while (n--)
>     {
>         array[i] = tags[iTags]; i--; iTags--;
>     }
>        
>     n = Math.floor(iterations / 64);
>     while (n--)
>     {
>         array[i] = tags[iTags]; i--; iTags--;
>        // 64 of the above line . . .
>     }
> }
> 
> 
> The Duff's Device improved performance as follows:
> 
> Firefox:
> push of 7000 elements without: 4.28s
> push of 7000 elements with: 2.08s
> 
> So that's pretty significant.
> 
> Of course, a simple Array.concat() of 7000 elements occurs in
> something 
> like .2s, and I really wish I could hit a performance number closer
> to 
> that - even 2s wasted on this trivial copy seems silly.
> 
> What performance tricks have others found to speed up this operation?
> 
> Thanks,
> -Chris "SoopahMan" Moschini
> 
> 
> Unsubscribe
> [email protected]
> 
> List info
> http://www.quirksmode.org/dom/list.html 
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 
> 
> 


-------------------| Jonathan Hurshman
-------------------| Pilgrim Web Design
-------------------| Brainbench MVP for JavaScript
-------------------|    http://www.brainbench.com

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 


Unsubscribe
[email protected]

List info
http://www.quirksmode.org/dom/list.html 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/wdf-dom/

<*> To unsubscribe from this group, send an email to:
    [email protected]

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/