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/