- From: Boris Zbarsky <bzbarsky@MIT.EDU>
- Date: Fri, 12 Feb 2010 11:29:11 -0500
- To: Anne van Kesteren <annevk@opera.com>
- CC: public-webapps@w3.org
On 2/12/10 8:05 AM, Anne van Kesteren wrote:
> Is it really a lot of performance? Our developers are not that convinced.
It depends on your use case.
If you're actually using getElementsByTagName on a largish DOM, then the
performance effect of not having to walk that DOM multiple times is in
fact significant. As a simple example, consider these four tests:
javascript:var start = new Date(); for (var counter = 0; counter <
100000; ++counter) { var str = counter + "";
document.getElementsByTagName(str); } var end = new Date(); alert(end -
start);
javascript:var start = new Date(); for (var counter = 0; counter <
10000; ++counter) { var str = counter + "";
document.getElementsByTagName(str).length; } var end = new Date();
alert(end - start);
javascript:var start = new Date(); for (var counter = 0; counter <
100000; ++counter) { var str = counter + "";
document.getElementsByTagName("foo"); } var end = new Date(); alert(end
- start);
javascript:var start = new Date(); for (var counter = 0; counter <
10000; ++counter) { var str = counter + "";
document.getElementsByTagName("foo").length; } var end = new Date();
alert(end - start);
Note that the tests that get the length run for 10x fewer iterations
than the ones that allow the implementation to just return an object and
do nothing. The ones that don't get the lengh are largely there to
measure object creation costs. The |counter + ""| thing is done in all
tests to eliminate that as a source of variability. I really hope the
various jits are not dead-code-eliminating it too much... ;)
The net result is that test 1 creates 100,000 objects, test 2 tries to
walk the DOM 10,000 times, test 3 and test 4 are like test 1 and 2
respectively in UAs that create new objects, and return cached objects
in ones that don't.
Running those on http://dromaeo.com/tests/dom-query.html gives me the
following numbers in Firefox:
Test 1: ~4350ms
Test 2: ~2100ms
Test 3: ~80ms
Test 4: ~10ms
and in Opera 10.5 pre alpha:
Test 1: ~520ms
Test 2: ~3809ms
Test 3: ~541ms
Test 4: ~3828ms
and in Safari 4:
Test 1: ~260ms
Test 2: ~1309ms
Test 3: ~131ms (?)
Test 4: ~20ms
Given that webkit doesn't cache the nodelist, I'm not sure how to
explain the Safari numbers; perhaps Maciej can do that.
In any case, as you can see avoiding the object-creation cost (test 1 vs
test 3) in Gecko is quite significant due to the expense of object
creation. It's a 50x speedup. As you can also see on the more useful
test, avoiding the DOM walk each time is a 20x speedup in this case.
This would obviously depend on the size of your DOM.
> Also it has been suggested to me that just-in-time optimizations might
> not work well if different users start polluting the same object (if
> nodelists are shared).
I would be interested in specifics here. Nothing we're doing in Gecko
comes to mind as a problem in that regard, especially since various
other things in the DOM _do_ in fact guarantee returning the same object.
-Boris
Received on Friday, 12 February 2010 16:29:52 UTC