- 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