Closed
Bug 934995
Opened 11 years ago
Closed 11 years ago
Speed up querySelectorAll by doing less allocations
Categories
(Core :: DOM: Core & HTML, defect)
Tracking
()
RESOLVED
FIXED
mozilla28
People
(Reporter: smaug, Assigned: smaug)
References
Details
(Whiteboard: [qa-])
Attachments
(2 files, 2 obsolete files)
3.90 KB,
patch
|
bzbarsky
:
review+
|
Details | Diff | Splinter Review |
3.93 KB,
patch
|
Details | Diff | Splinter Review |
I was wrong about nsAutoTArray. I can see some improvement if we do allocation just once (in common cases). gcc doesn't inline the template function without MOZ_ALWAYS_INLINE, yet in this case inline makes lots of sense. nsAutoTArray is unfortunately there even for the onlyFirstMatch case, but shouldn't be too bad, based on assembly. https://tbpl.mozilla.org/?tree=Try&rev=1d6555cc2413
Attachment #827393 -
Flags: review?(bzbarsky)
Comment 1•11 years ago
|
||
Comment on attachment 827393 [details] [diff] [review] patch We don't need the nsAutoTArray in the onlyFirstMatch case, do we? What we should do instead is declare an nsAutoTArray in QuerySelectorAll and pass _that_ as the third arg to FindMatchingElements, so all the appending automatically happens to the nsAutoTArray in that case. And then the querySelector case won't be affected at all. As far as then putting the elements into the nsContentList, I'd rather expose something that takes an nsTArray and SwapElements() with it; this would be very fast if we had to heap-allocate our auto array, and much like your manual SetCapacity and append loop otherwise, right?
Attachment #827393 -
Flags: review?(bzbarsky) → review-
Assignee | ||
Comment 2•11 years ago
|
||
We can't do SwapElements since we want to collect elements as Element* but contentlist keeps them alive as nsCOMPtr<Element>. But I'll make that change to pass nsAutoTArray as param.
Assignee | ||
Comment 3•11 years ago
|
||
Though, that approach is slower in case there are id selectors and also in case someone passes invalid selecter (jquery for example). Need to do some template magic
Assignee | ||
Comment 4•11 years ago
|
||
Compiler seems to optimize out that dummy for loop in case of QuerySelector.
Attachment #827393 -
Attachment is obsolete: true
Attachment #827537 -
Flags: review?(bzbarsky)
Comment 5•11 years ago
|
||
> Though, that approach is slower in case there are id selectors Hmm. Why? > and also in case someone passes invalid selecter Because in that case we do the auto array ctor/dtor even in cases when we're going to throw an exception, right? We can address this with using a wrapper around a Maybe<nsAutoTArray> as the class to put stuff into. That seems like it would be clearer than loops that we depend on optimizing away and AppendElement calls in both branches of an if. But I'd like to understand why this has any particular extra cost in the id case, any more than in any other case...
Flags: needinfo?(bugs)
Assignee | ||
Comment 6•11 years ago
|
||
With id case I mean the code in FindMatchingElements which deals with id selectors. Usually those should return zero or one results. If we create nsAutoTArray in nsINode::QuerySelectorAll, we create and destroy it always, even if FindMatchingElements throws or returns just one result for the id selector.
Flags: needinfo?(bugs)
Comment 7•11 years ago
|
||
> Usually those should return zero or one results.
Ah, so we end up doing just the one append and one allocation and all the auto array stuff is pure overhead, ok.
So one option is to use a Maybe<nsAutoTArray>, only init it after the exception/id cases, and use a different API (AppendElementBatched or something?) for appending things when we want them appended to the AutoTArray in the AutoTArray case. Does that make sense?
Assignee | ||
Comment 8•11 years ago
|
||
How is that better. We'd need to have if (!onlyFirstMatch) maybeThing.construct(); That isn't really much different to ElementHolder foo; (which is just a container for one null value.) The if (onlyFirstMatch) { is already there in the loop. Not sure how the AppendElement in it makes it worse. The end of the method is very much no-op in onlyFirstMatch case and seems to be optimized out in onlyFirstMatch case. Maybe<> isn't totally free either. But I don't know... I've written this in few different ways and nothing is super pretty, but at least atm I prefer the approach the patch has.
Comment 9•11 years ago
|
||
> We'd need to have >if (!onlyFirstMatch) > maybeThing.construct(); Nah, you'd construct it always but have the thing that the onlyFirstMatch case passes in have a no-op construct() method. >Maybe<> isn't totally free either. True... >and seems to be optimized out in onlyFirstMatch case. I'm just slightly worried about how much we can rely on that. Would it help if we were more explicit about doing all that loop stuff if (!onlyFirstMatch)? And in that case, could we even use a Collector class that has no methods on it, to make sure that code is not even being compiled in the onlyFirstMatch case? I wonder whether that would compile....
Assignee | ||
Comment 10•11 years ago
|
||
The thing doesn't compile if SetCapacity etc aren't defined in the ElementHolder (even if 'if (!onlyFirstMatch)' is used). if (len) (where len is always 0) should be pretty strong hint to compiler to optimize that out, and using length and not onlyFirstMatch let's us optimize out the case there are no results and onlyFirstMatch is false.
Attachment #827537 -
Attachment is obsolete: true
Attachment #827537 -
Flags: review?(bzbarsky)
Attachment #828224 -
Flags: review?(bzbarsky)
Comment 11•11 years ago
|
||
Comment on attachment 828224 [details] [diff] [review] v3 >+ void SetCapacity(uint32_t aCapacity) {} >+ Element* ElementAt(uint32_t aIndex) { return nullptr; } Maybe assert notreached for those? r=me
Attachment #828224 -
Flags: review?(bzbarsky) → review+
Assignee | ||
Comment 12•11 years ago
|
||
Assignee | ||
Comment 13•11 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/1eeb08e557c2
https://hg.mozilla.org/mozilla-central/rev/1eeb08e557c2
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla28
Updated•10 years ago
|
Whiteboard: [qa-]
Updated•5 years ago
|
Component: DOM → DOM: Core & HTML
You need to log in
before you can comment on or make changes to this bug.
Description
•