Hi, Ricardo, I agree with you. Maybe it's not such a performance lost to do this method prepared for easy reading... :-) I'll put some new implementation in the next e-mail, where I answer Diego's one... ;-)
About the code: checkout here: https://jqbench.svn.sourceforge.net/svnroot/jqbench/jquery_branches/1.2.6 Yeah, I now, the code is a [EMAIL PROTECTED]&(#$ mess, but it started just as a performance difference analysis for JS 1.6's "forEach" Array method, its hard-coded implementation (consistent with Mozilla's algorithmn) and jQuery's $.each(). As I stated earlier, I promise to make something better later. Thanks! Diogo ricardobeat escreveu: > Hello Diogo, > > Your last implementations are still not compatible with other document > contexts themselves. Most of the difference in performance comes from > the overhead of checking the ownerDocument and corresponding > documentElement for the element, and you left that out of the > equation. It seems to me the gain in speed is marginal in comparison > to the code size and obscurity :) > > BTW, do you mind sharing your test setup for these? I'm getting much > lower times for 1000 iterations. > > cheers, > -ricardo > > On 4 dez, 02:15, Diogo Baeder <[EMAIL PROTECTED]> wrote: > >> Alright... I made some tests, but now keeping support for iframes and >> XML documents. Though hoping not to be boring everyone here, I'd like to >> share the results (same 1000 iterations) - note that some of them expect >> a context argument, if you're willing to use iframes or XML (maybe we >> have least situations like these, am I right?): >> >> - IMPLEMENTATIONS: >> >> $.fn.inDOM4 = function() { >> var el = this[0], doc = el && el.ownerDocument && >> el.ownerDocument.documentElement; >> return !!doc && (doc.contains ? doc.contains(el) : >> !!(doc.compareDocumentPosition(el) & 16)); >> }; >> >> // Fifth implementation, including extra methods (that might be >> usefull) in jQuery >> $.contains = docEl.contains ? >> function(a, b) { >> return a && b && a != b && a.contains(b); >> } : >> function(a, b) { >> return a && b && a != b && !!a.compareDocumentPosition(b) & 16; >> }; >> $.fn.contains = function(el) { >> return $.contains(this[0], el); >> }; >> $.fn.inDOM5 = function(contextEl) { >> var doc = contextEl || document.documentElement; >> return $.contains(doc, this[0]); >> }; >> >> $.fn.inDOM6 = function() { >> var el = this[0], doc = el && el.ownerDocument && >> el.ownerDocument.documentElement; >> return $.contains(doc, this[0]); >> }; >> >> $.fn.inDOM7 = docEl.contains ? >> function(contextEl) { >> var el = this[0], doc = contextEl || document.documentElement; >> return doc && el && doc != el && docEl.contains(el); >> } : >> function(contextEl) { >> var el = this[0], doc = contextEl || document.documentElement; >> return doc && el && doc != el && >> !!(docEl.compareDocumentPosition(el) & 16); >> }; >> >> - PERFORMANCE RESULTS: >> >> ===== inDOM4 ===== >> start: 1228363385834 ms >> end: 1228363385916 ms >> difference: 82 ms >> >> ===== inDOM5 ===== >> start: 1228363386080 ms >> end: 1228363386124 ms >> difference: 44 ms >> >> ===== inDOM6 ===== >> start: 1228363386319 ms >> end: 1228363386391 ms >> difference: 72 ms >> >> ===== inDOM7 ===== >> start: 1228363386563 ms >> end: 1228363386601 ms >> difference: 38 ms >> >> Also, I'm tending to think "isOrphan", as suggested before (was it >> Mevin?), is a more adequate name (considering a boolean inversion in the >> function return), since a code like "if (el.isOrphan()) return;" seems >> more readable to me... what do you guys think? >> >> And sorry for the numerous postings... :-) >> >> Diogo >> >> Ariel Flesler escreveu: >> >> >>> For an element from any other document. >>> >>> Examples: >>> - IFrames >>> - XML >>> - Other documents >>> >>> On Wed, Dec 3, 2008 at 4:44 PM, Diogo Baeder <[EMAIL PROTECTED]> wrote: >>> >>>> Alright, but what is the difference between "document" and >>>> "el.ownerDocument"? I tested: >>>> >>>> alert(document.getElementsByTagName('body')[0].ownerDocument == document); >>>> >>>> And it returns true... which are the cases where this may return false? >>>> >>>> Diogo >>>> >>>> On Wed, Dec 3, 2008 at 4:27 PM, Ariel Flesler <[EMAIL PROTECTED]> wrote: >>>> >>>>> That's what I was sort of suggesting, el.ownerDocument.documentElement, >>>>> that is. >>>>> >>>>> As someone said (don't recall and don't wanna read up), good browsers >>>>> (w3) do set ownerDocument to null when the node is outside any >>>>> document. >>>>> >>>>> Assuming that's true: >>>>> >>>>> $.fn.inDOM = function(){ >>>>> var elem = this[0], >>>>> doc = el && el.ownerDocument && el.ownerDocument.documentElement; >>>>> >>>>> return !!doc && (doc.contains ? >>>>> doc.contains(el) >>>>> : !!(doc.compareDocumentPosition(el) & 16) >>>>> ); >>>>> }; >>>>> >>>>> On Wed, Dec 3, 2008 at 4:15 PM, ricardobeat <[EMAIL PROTECTED]> wrote: >>>>> >>>>>> Why not simplify? >>>>>> >>>>>> $.fn.inDOM = function(){ >>>>>> var el=this[0]; >>>>>> if (!el) return false; >>>>>> var doc = el.ownerDocument.documentElement; >>>>>> return (doc.contains) >>>>>> ? doc.contains(el) >>>>>> : !!(doc.compareDocumentPosition(el) & 16); >>>>>> }; >>>>>> >>>>>> 36ms vs 12ms for Diogo's 'inDOM3Optimized', but keeps it compatible >>>>>> with other 'document' contexts. That's 1000 iterations, I don't see >>>>>> anyone having thousands of elements that he doesn't know if are in the >>>>>> DOM or not. It works in all target browsers, so the parentNode >>>>>> fallback is not needed. >>>>>> >>>>>> Ariel, is there any situation where a node has no ownerDocument/ >>>>>> documentElement property? >>>>>> >>>>>> - ricardo >>>>>> >>>>>> On Dec 3, 11:21 am, "Ariel Flesler" <[EMAIL PROTECTED]> wrote: >>>>>> >>>>>>> Those functions relying on $('html') wouldn't work for xml or some >>>>>>> other special kind of document (namespaced tagnames?). >>>>>>> >>>>>>> I think it is indeed better to rely on the documentElement of the >>>>>>> ownerDocument (if the latter exists else just false). >>>>>>> >>>>>>> On Wed, Dec 3, 2008 at 12:40 AM, Diogo Baeder <[EMAIL PROTECTED]> >>>>>>> wrote: >>>>>>> >>>>>>>> Diego, if I can recall, I already tested el.ownerDocument and, in >>>>>>>> IE6, >>>>>>>> it always returned true in Boolean test, even if the element was >>>>>>>> removed. >>>>>>>> >>>>>>>> The "bifurcated" implementation was tested in all browsers with >>>>>>>> success >>>>>>>> (except for FF2, which I didn't have in my machine at the time): FF3, >>>>>>>> IE6, IE7, Safari 3.1.2 and Opera 9.62. >>>>>>>> >>>>>>>> About the method name, it's a good point... ok by me to change it to >>>>>>>> "isOrphan" and invert the return from the past implementation... >>>>>>>> >>>>>>>> I also updated the implementations and testing in the benchmark, >>>>>>>> putting >>>>>>>> a "return false" if no element is false (correcting, thus, the bugs >>>>>>>> of >>>>>>>> when the elements were removed from DOM) and setting $('#level10') to >>>>>>>> a >>>>>>>> variable (in the "deep-level" testing), thus eliminating the need for >>>>>>>> a >>>>>>>> new traversal in every loop iteration. Here they are: >>>>>>>> >>>>>>>> ----- IMPLEMENTATIONS: >>>>>>>> >>>>>>>> $.fn.inDOM1 = function() { >>>>>>>> return !!$(this).parents('html').length; >>>>>>>> }; >>>>>>>> >>>>>>>> $.fn.inDOM2 = function() { >>>>>>>> var el = this[0]; >>>>>>>> if (!el) return false; >>>>>>>> while (el.parentNode) el = el.parentNode; >>>>>>>> return el.nodeType == 9; >>>>>>>> }; >>>>>>>> >>>>>>>> $.fn.inDOM3 = function() { >>>>>>>> var el = this[0]; >>>>>>>> if (!el) return false; >>>>>>>> var html = $('html').get(0); >>>>>>>> return html.contains ? >>>>>>>> html != el && html.contains(el) : >>>>>>>> !!(html.compareDocumentPosition(el) & 16); >>>>>>>> }; >>>>>>>> >>>>>>>> var docEl = document.documentElement; >>>>>>>> $.fn.inDOM3Optimized = docEl.contains ? >>>>>>>> function() { >>>>>>>> var el = this[0]; >>>>>>>> if (!el) return false; >>>>>>>> return docEl != el && docEl.contains(el); >>>>>>>> } : >>>>>>>> function() { >>>>>>>> var el = this[0]; >>>>>>>> if (!el) return false; >>>>>>>> return !!(docEl.compareDocumentPosition(el) & 16); >>>>>>>> }; >>>>>>>> >>>>>>>> --- PERFORMANCE RESULTS: >>>>>>>> >>>>>>>> ===== inDOM1: parents("html") ===== >>>>>>>> start: 1228270728766 ms >>>>>>>> end: 1228270729258 ms >>>>>>>> difference: 492 ms >>>>>>>> >>>>>>>> ===== inDOM2: parentNode ===== >>>>>>>> start: 1228270729274 ms >>>>>>>> end: 1228270729437 ms >>>>>>>> difference: 163 ms >>>>>>>> >>>>>>>> ===== inDOM3: html.contains() ===== >>>>>>>> start: 1228270729450 ms >>>>>>>> end: 1228270729808 ms >>>>>>>> difference: 358 ms >>>>>>>> >>>>>>>> ===== inDOM3Optimized: html.contains() ===== >>>>>>>> start: 1228270729821 ms >>>>>>>> end: 1228270729911 ms >>>>>>>> difference: 90 ms >>>>>>>> >>>>>>>> ===== inDOM2: traversing 10 levels ===== >>>>>>>> start: 1228270729924 ms >>>>>>>> end: 1228270730161 ms >>>>>>>> difference: 237 ms >>>>>>>> >>>>>>>> ===== inDOM3Optimized: traversing 10 levels ===== >>>>>>>> start: 1228270730173 ms >>>>>>>> end: 1228270730184 ms >>>>>>>> difference: 11 ms >>>>>>>> >>>>>>>> ===== inDOM2: after removal ===== >>>>>>>> start: 1228270730198 ms >>>>>>>> end: 1228270730382 ms >>>>>>>> difference: 184 ms >>>>>>>> >>>>>>>> ===== inDOM3Optimized: after removal ===== >>>>>>>> start: 1228270730395 ms >>>>>>>> end: 1228270730405 ms >>>>>>>> difference: 10 ms >>>>>>>> >>>>>>>> Note: inDOM2 is the impl. using parentNode, and inDOM3 is the one >>>>>>>> using >>>>>>>> special methods ("bifurcated code"). >>>>>>>> Note 2: the speed in "inDOM3Optimized" changed a lot just because I >>>>>>>> setted $('level10') to a variable before all the tests. This >>>>>>>> strengthens >>>>>>>> the performance reason to favor the "bifurcated code" implementation. >>>>>>>> ;-) >>>>>>>> >>>>>>>> If everybody agrees with the method name change (to "isOrphan"), >>>>>>>> which >>>>>>>> is OK by me, I can do it in the benchmarks to keep consistency with a >>>>>>>> possible future version of jQuery. >>>>>>>> >>>>>>>> Diogo >>>>>>>> >>>>>>>> Diego Perini escreveu: >>>>>>>> >>>>>>>>> John, >>>>>>>>> I believe there is an error, probably you meant: >>>>>>>>> >>>>>>>>> $.fn.inDOM = document.documentElement.contains ? >>>>>>>>> function() { >>>>>>>>> var el = this[0], root = el.ownerDocument.documentElement; >>>>>>>>> return root !== el && root.contains(el); >>>>>>>>> } : >>>>>>>>> function() { >>>>>>>>> var el = this[0]; >>>>>>>>> return !! >>>>>>>>> (el.ownerDocument.documentElement.compareDocumentPosition(el) & 16); >>>>>>>>> }; >>>>>>>>> >>>>>>>>> or if you prefer in the declaration "var el = >>>>>>>>> this[0].ownerDocument". >>>>>>>>> >>>>>>>>> As I already said, the native methods are the fastest, no doubt, but >>>>>>>>> the standalone version is still to be considered alone or combined. >>>>>>>>> >>>>>>>>> However, I believe we should test the following minor implications >>>>>>>>> if >>>>>>>>> deemed >>>>>>>>> >> ... >> >> mais ยป >> > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "jQuery Development" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/jquery-dev?hl=en -~----------~----~----~----~------~----~------~--~---
