Oops, I found an important bug in the previous version of the code.
I fixed it. Fewer look-ups by the way, seems to be insignificantly
faster.

The code on gist is now a plugin ready for testing: 
http://gist.github.com/169693

On Aug 20, 12:48 pm, Samer Ziadeh <samerzia...@gmail.com> wrote:
> sweet, does that mean 1.3.3 will be super fast?
>
> On Wed, Aug 19, 2009 at 14:06, lrbabe <lrb...@gmail.com> wrote:
>
> > I've created a ticket and submitted a patch, I was going to forget
> > about it otherwise:http://dev.jquery.com/ticket/5076
>
> > On Aug 18, 2:11 pm, lrbabe <lrb...@gmail.com> wrote:
> > > I re-wrote .filter() this morning:http://gist.github.com/169693
> > > Here are the new profiling outputs (I repeat the previous ones for
> > > convenience):
>
> > > 1. With the orginal .filter() and .closest() implementations:
> > > - entering the ul: function calls = 76, time = 1.5 to 2.5 ms
> > > - moving from a li to a li.blue: calls = 144, time ~= 3.2ms
> > > - moving from a li.blue to a li: calls = 103, time ~= 2.2ms
> > > - moving from a li to a green span: calls = 124, time ~= 2.2ms
> > > - moving from a green span to a red span: calls = 145, time ~= 3.2ms
>
> > > 2. With the modified .closest() implementation:
> > > - entering the ul: function calls = 13, time ~= 0.25ms
> > > - moving from a li to a li.blue: calls = 27, time ~= 0.55ms
> > > - moving from a li.blue to a li: calls = 13, time ~= 0.25ms
> > > - moving from a li to a green span: calls = 13, time ~= 0.3ms
> > > - moving from a green span to a red span: calls = 13, time ~= 0.3ms
>
> > > 3. With the modified .filter() implementation and a specific cache:
> > > - entering the ul: function calls = 28, time ~= 0.57ms
> > > - moving from a li to a li.blue: calls = 52, time ~= 0.9ms
> > > - moving from a li.blue to a li: calls = 33, time ~= 0.6ms
> > > - moving from a li to a green span: calls = 38, time ~= 0.67ms
> > > - moving from a green span to a red span: calls = 43, time ~= 0.73ms
>
> > > It's approximately 2x slower when the optimization is in .filter().
> > > Compared to the original implementation there is still a clear
> > > benefit.
> > > Again, this is a very simple page that I'm testing on a pretty fast
> > > configuration.
> > > The benefit in real conditions for IE users would be even more
> > > significant.
>
> > > I've made two other tests to inform the way of caching the parsed
> > > selector
>
> > > 4. With the modified .filter() implementation and using jQuery.data
> > > (window, "parsedCache"):
> > > - entering the ul: function calls = 31, time = 0.6ms to 0.95ms
> > > - moving from a li to a li.blue: calls = 57, time ~= 1.3ms
> > > - moving from a li.blue to a li: calls = 37, time ~= 0.75ms
> > > - moving from a li to a green span: calls = 43, time ~= 0.8ms
> > > - moving from a green span to a red span: calls = 49, time ~= 0.9ms
>
> > > 5. With the modified .filter() implementation without caching the
> > > parsed selector:
> > > - entering the ul: function calls = 28, time = 0.6ms to 0.9ms
> > > - moving from a li to a li.blue: calls = 52, time ~= 1ms to 1.2ms
> > > - moving from a li.blue to a li: calls = 33, time ~= 0.7ms
> > > - moving from a li to a green span: calls = 38, time ~= 0.84ms
> > > - moving from a green span to a red span: calls = 43, time ~= 0.93ms
>
> > > As I expected, there is a benefit in using a cache, but there doesn't
> > > appear to be any benefit in using .data() for that purpose.
>
> > > Regards,
>
> > > Louis-Rémi
>
> > > On Aug 18, 2:02 am, lrbabe <lrb...@gmail.com> wrote:
>
> > > > I was also wondering what kind of selectors jQuery.expr was used for.
> > > > From my own experience, there is a clear benefit in .closest because I
> > > > almost exclusively use selectors of the form "div" or ".class".
> > > > But I just realized that .hasClass() would also benefit from this
> > > > optimization with its current implementation, and I use .hasClass() a
> > > > lot!
>
> > > > On Aug 18, 1:00 am, lrbabe <lrb...@gmail.com> wrote:
>
> > > > > It would definitely make sense of course.
>
> > > > > What I really wanted was to minimize the impact of this extra-
> > > > > processing on complex selectors.
> > > > > In .closest(), even if you don't use any kind of cache, you parse the
> > > > > selector only once every time you use the function.
> > > > > If the optimization lies jQuery.filter then the cache becomes much
> > > > > more important.
> > > > > Since I'm not sure what kind of caching mechanism to use (would .data
> > > > > () be faster than re-parsing the selector?), I wasn't feeling
> > > > > confident enough to propose this change for .filter().
>
> > > > > There was also an optimization in .closest() for position selectors
> > > > > (:first, :last, ...). I don't know what it was here for (I never use
> > > > > such selectors for event delegation), but it wasn't in jQuery.filter.
>
> > > > > What would you recommend?
>
> > > > > Louis-Rémi
>
> > > > > On Aug 17, 10:44 pm, John Resig <jere...@gmail.com> wrote:
>
> > > > > > I'm curious as to why you only chose to optimize the selectors in
> > .live().
> > > > > > Why not optimize .is()? or jQuery.filter? Optimizing jQuery.filter
> > would
> > > > > > yield faster results for .filter(), .is(), and .live().
>
> > > > > > --John
>
> > > > > > On Mon, Aug 17, 2009 at 1:38 PM, lrbabe <lrb...@gmail.com> wrote:
>
> > > > > > > I've made some minor updates to the code to reduce the code size:
> > > > > > > - it now uses the internal jQuery.nodeName function to check for
> > > > > > > simple selectors involving a node name (which is also safer)
> > > > > > > - it checks for simple selectors before checking for position
> > > > > > > selectors
> > > > > > > The size difference for the minified version between the current
> > > > > > > implementation and this new one should be around 250B
> > > > > > > The code is at the same address:http://gist.github.com/168158
>
> > > > > > > I'm also willing to write on learningjquery.com about the new
> > features
> > > > > > > for event delegation introduced in jQuery 1.3: live and closest
> > > > > > > Who should I contact for that purpose?
>
> > > > > > > Regards,
> > > > > > > Louis-Rémi Babé
>
> > > > > > > On Aug 15, 2:23 am, lrbabe <lrb...@gmail.com> wrote:
> > > > > > > > Thank for your quick answer John,
>
> > > > > > > > All right, I take the code of the example, remove the part that
> > > > > > > > updates the counter and wraps the rest with a console.profile()
>
> > > > > > > > 1. With the orginal .closest() implementation:
> > > > > > > > - entering the ul: function calls = 76, time = 1.5 to 2.5 ms
> > > > > > > > - moving from a li to a li.blue: calls = 144, time ~= 3.2ms
> > > > > > > > - moving from a li.blue to a li: calls = 103, time ~= 2.2ms
> > > > > > > > - moving from a li to a green span: calls = 124, time ~= 2.2ms
> > > > > > > > - moving from a green span to a red span: calls = 145, time ~=
> > 3.2ms
> > > > > > > > 2. With the modified .closest() implementation:
> > > > > > > > - entering the ul: function calls = 13, time ~= 0.25ms
> > > > > > > > - moving from a li to a li.blue: calls = 27, time ~= 0.55ms
> > > > > > > > - moving from a li.blue to a li: calls = 13, time ~= 0.25ms
> > > > > > > > - moving from a li to a green span: calls = 13, time ~= 0.3ms
> > > > > > > > - moving from a green span to a red span: calls = 13, time ~=
> > 0.3ms
>
> > > > > > > > ...and we have only three levels of elements here.
>
> > > > > > > > On Aug 15, 1:51 am, John Resig <jere...@gmail.com> wrote:
>
> > > > > > > > > An interesting proposition - although before making a change
> > of this
> > > > > > > > > magnitude it would be good to get some performance numbers
> > outlined so
> > > > > > > that
> > > > > > > > > we know how worthwhile it is.
>
> > > > > > > > > --John
>
> > > > > > > > > On Fri, Aug 14, 2009 at 8:33 PM, lrbabe <lrb...@gmail.com>
> > wrote:
>
> > > > > > > > > > Hi,
>
> > > > > > > > > > The principle of .closest( selector ) is that it cycles
> > through the
> > > > > > > > > > ancestors of an event target until it finds an element
> > corresponding
> > > > > > > > > > to the event target, or hits the root.
> > > > > > > > > > To check for an element matching the selectors it uses the
> > .is
> > > > > > > > > > ( selector ) function which collects all elements
> > corresponding to
> > > > > > > the
> > > > > > > > > > selector and cycles through them to find if "this" is any
> > of those
> > > > > > > > > > elements.
>
> > > > > > > > > > If my memories about my algorithm lectures are correct, the
> > > > > > > complexity
> > > > > > > > > > of this algorithm is O(n²). Only in the case of a selector
> > of the
> > > > > > > form
> > > > > > > > > > "#id" we have an O(n) complexity.
> > > > > > > > > > However, there is another range of selectors that could be
> > checked
> > > > > > > > > > with an O(n) algorithm: selectors such as "div", ".class"
> > and
> > > > > > > > > > "div.class". In those cases, .is( selector ) is not needed
> > because we
> > > > > > > > > > can directly check the ancestor's nodeType and className.
>
> > > > > > > > > > Reducing the complexity of the .closest() function is
> > particularly
> > > > > > > > > > important when using event delegation with the mouseover
> > and mouseout
> > > > > > > > > > events: those events fire really often as the user moves
> > his/her
> > > > > > > > > > mouse, and the function needs to be used twice: one to
> > check the the
> > > > > > > > > > target is in the selector, and one to check that the
> > related target
> > > > > > > is
> > > > > > > > > > in a different ancestor.
>
> > > > > > > > > > I propose a new implementation of .closest() that is able
> > to detect
> > > > > > > > > > those selectors and use them to "fast-check" ancestors. The
> > last
> > > > > > > > > > parsed selector is cached to further improve the
> > performances (I'm
> > > > > > > > > > just not sure where to cache the parsed selector).
>
> > > > > > > > > > The code is available as a gist:
> >http://gist.github.com/168158
> > > > > > > > > > and can be tested here:
> >http://www.lrbabe.com/sdoms/closest/
>
> > > > > > > > > > Together with the recent addition of the "context"
> > parameter
> > > > > > > > > > in .closest(), it makes one of the most efficient event
> > delegation
>
> ...
>
> read more »
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"jQuery Development" group.
To post to this group, send email to jquery-dev@googlegroups.com
To unsubscribe from this group, send email to 
jquery-dev+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/jquery-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to