I poked around even more to see if there could be anythings improved.

I added tests for querySelectorAll, Xpath and native
nextSiblingElement (if present).

Alas, with qsa is quite tricky to simulate siblings -- I had to set
and unset attributes to achieve it and to use [] and :not selectors.

XPath has rules for siblings (preceding and following, but not all) --
fairly simple, but quite slow (why?).

While in FF 3.5.2 siblingsKangax rulles them all in Opera 9.5 and
Chromium Portable things tend to be different.

http://groups.google.com/group/prototype-core/web/element%23siblings%20%282%29.zip

On Sep 3, 4:47 pm, kangax <kan...@gmail.com> wrote:
> `adHocSiblings` is clearly faster. I guess since it avoids 2 extra
> function calls (`previousSiblings` and `nextSiblings`).
>
> Running a simple test based on your example page:
>
> var tdEl = document.getElementsByTagName('td')[100];
>
> var t = new Date();
> for (var i=1000; i--; ) protoSiblings(tdEl);
> var t1 = new Date() - t;
>
> t = new Date();
> for (var i=1000; i--; ) adHocSiblings(tdEl);
> var t2 = new Date() - t;
>
> t = new Date();
> for (var i=1000; i--; ) siblings2(tdEl);
> var t3 = new Date() - t;
>
> document.write(
>   'protoSiblings: ' + t1 + 'ms;<br>'+
>   'adHocSiblings: ' + t2 + 'ms;<br>'+
>   'siblings2: '     + t3 + 'ms');
>
> where `siblings2` is practically your `adHocSiblings`, but with few
> more optimizations (such as do-while instead of while-do, as well as
> removal of `push` and `arguments`) -
>
> function siblings2(element) {
>   if (!element) return [];
>   var originalElement = element, elements = [], i = 0;
>   element = element.parentNode.firstChild;
>   do {
>     if (element.nodeType == 1 && element != originalElement) {
>       elements[i++] = element;
>     }
>   } while (element = element.nextSibling)
>   return elements;
>
> }
>
> === FF 3.5.2
> protoSiblings: 41ms;
> adHocSiblings: 23ms;
> siblings2: 19ms
>
> === Opera 10
> protoSiblings: 78ms;
> adHocSiblings: 61ms;
> siblings2: 45ms
>
> === Safari 3.2.1
> protoSiblings: 28ms;
> adHocSiblings: 17ms;
> siblings2: 14ms
>
> --
> kangax
>
> On Sep 3, 5:33 am, Иван Жеков <jon...@gmail.com> wrote:
>
> > Actually I did make a test case 
> > --http://groups.google.com/group/prototype-core/web/element%23siblings....
> > zipped to take less space from the quota.
>
> > For fair tests, I extracted the methods as simple functions.
>
> > Note:
> > * The first click is noticably slower then the rest of the clicks.
> > * Actual exectution vary for me on every page refresh.
>
> > I get 5ms for the ad hoc method and 7 for the proto method.
>
> > 2009/9/3 kangax <kan...@gmail.com>
>
> > > On Sep 2, 6:25 pm, joneff <jon...@gmail.com> wrote:
> > > > (It's kinda long and it might be for the other prototype group, but I
> > > > am not sure.)
>
> > > > I was poking around with a script for manipulating tables which takes
> > > > heavy use of Element#siblings for some of the manips.
>
> > > > And I found that in some cases it [the method] tends to be slow. Not
> > > > slow like "Vista on a 486 PC" but slow as in "a bit slower than I
> > > > expected".
>
> > > > But then again I am usually testing on 1000 row tables with enough
> > > > cols to make FF choke and was like "maybe it's supposed to be like
> > > > that. maybe if I use querySelectorAll it will be faster".
>
> > > > I mean, I do remember an immediate following sibling selector (+) and
> > > > all following siblings selector (~). It seemed to me, that there
> > > > should be ALL siblings selector. Alas I was wrong. Not to mention it's
> > > > kinda wicked to work with qSA.
>
> > > > So what I did was to dig in prototype code and find the
> > > > Element#siblings. I admit it's logic is perfect -- ALL siblings = next
> > > > siblings + following siblings. The only thing that bothered me was the
> > > > amount of function calls -- I mean this function call that function,
> > > > and calls another one, and another one and so on and so forth.
>
> > > > Note: I am do CSS for a living. Thus I have absolutely no idea how
> > > > much time it takes (if any) to jump from a function to function.
>
> > > > Anyway, I made my way up the function, trying to keep the code general
> > > > feeling and I was left with this
>
> > > > siblngs: function (element) {
> > > >         if (!element) return [];
> > > >         element = element.parentNode.firstChild, elements = [];
> > > >         while (element) {
> > > >                 if (element.nodeType == 1 && element != arguments[0])
> > > elements.push
> > > > (Element.extend(element));
> > > >                 element = element.nextSibling;
> > > >         }
> > > >         return elements;
>
> > > > }
>
> > > > which, I have to admit wasn't as faster as I expected.
>
> > > > Anyway, I went over to jQ and mT to see how they do it.
>
> > > > jQ's approach was more or less similar. It does use this weird for
> > > > statement (translated to fit) -- (;element;element.nextSibling) --
> > > > instead of the while, but the I guess that wouldn't make a difference.
>
> > > > mT was even more exotic then the original Prototype method, but kinda
> > > > has the same spirit as the one above.
>
> > > > Sooo... Like I noticed in the beginning, that was long, and I am still
> > > > not sure it's for this group, and I having in mind I do CSS for a
> > > > living, I am asking -- is this "improved" Element#siblings faster?
>
> > > Why not make a simple test case to see if it really is faster?
>
> > > --
> > > kangax
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to 
prototype-core-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to