Closed
Bug 454280
Opened 16 years ago
Closed 16 years ago
[FIX]nsContentList performance improvements
Categories
(Core :: DOM: Core & HTML, defect)
Tracking
()
RESOLVED
FIXED
People
(Reporter: bzbarsky, Assigned: bzbarsky)
References
Details
(Keywords: perf)
Attachments
(1 file, 3 obsolete files)
10.37 KB,
patch
|
Details | Diff | Splinter Review |
I did some nsContentList profiling for bug 453929, and think that we can make things a bit faster here. Patch should be coming up pretty soon.
![]() |
Assignee | |
Updated•16 years ago
|
![]() |
Assignee | |
Comment 1•16 years ago
|
||
This speeds up the tree walk a good bit. The main changes are:
1) Make the IsNodeOfType() check as early as we can, so we can avoid all the
function call overhead for the (plentiful) textnodes.
2) Use NS_FASTCALL on the method that does the actual walking.
3) Use a faster way to iterate the kids (fewer virtual calls).
Taken together, these make the dromaeo tests that actually test this code (so the getElementsByClassName and getElementsByName tests) almost 1.8x faster.
Attachment #337588 -
Flags: superreview?(jonas)
Attachment #337588 -
Flags: review?(jonas)
Comment 2•16 years ago
|
||
FWIW, quite a few of the dromaeo DOM tests spend some significant time in nsContentList, so this is likely to improve the general benchmark by a fair bit.
Attachment #337588 -
Flags: superreview?(jonas)
Attachment #337588 -
Flags: superreview+
Attachment #337588 -
Flags: review?(jonas)
Attachment #337588 -
Flags: review+
Comment on attachment 337588 [details] [diff] [review]
Make it faster
>@@ -665,20 +670,16 @@ nsContentList::Match(nsIContent *aConten
Could you add an assertion to the top of nsContentList::Match to make sure that aContent is an element? That seems to be the general idea here right?
Also, this means that we can't make content-lists containing things other than elements, right?
>@@ -761,22 +779,25 @@ nsContentList::PopulateWithStartingAfter
> if (aStartChild) {
> i = aStartRoot->IndexOf(aStartChild);
> NS_ASSERTION(i >= 0, "The start child must be a child of the start root!");
> ++i; // move to one past
> }
>
> PRUint32 childCount = aStartRoot->GetChildCount();
> for ( ; ((PRUint32)i) < childCount; ++i) {
>- PopulateWith(aStartRoot->GetChildAt(i), aElementsToAppend);
>-
>- NS_ASSERTION(aElementsToAppend + mElements.Count() == invariant,
>- "Something is awry in PopulateWith!");
>- if (aElementsToAppend == 0)
>- return;
>+ nsIContent* content = aStartRoot->GetChildAt(i);
>+ if (content->IsNodeOfType(nsINode::eELEMENT)) {
>+ PopulateWith(content, aElementsToAppend);
>+
>+ NS_ASSERTION(aElementsToAppend + mElements.Count() == invariant,
>+ "Something is awry in PopulateWith!");
>+ if (aElementsToAppend == 0)
>+ return;
>+ }
Why not use the GetChildArray trick here too?
Also, you could make GetChildArray return both a length and an array pointer (one of the two through an out param) in order to avoid one virtual call.
r/sr=me either way
![]() |
Assignee | |
Comment 4•16 years ago
|
||
> Could you add an assertion to the top of nsContentList::Match
Done.
> Also, this means that we can't make content-lists containing things other than
> elements, right?
Yes. We never do right now, and I couldn't think of use cases, so much.
> Why not use the GetChildArray trick here too?
It didn't pop up as a hotspot in this particular profile. You're right that I should; I've made that change.
> Also, you could make GetChildArray return both a length and an array pointer
Filed bug 454821. That depends on killing EnsureContentsGenerated.
![]() |
Assignee | |
Comment 5•16 years ago
|
||
Attachment #337588 -
Attachment is obsolete: true
Hmm.. just realized, why not put the IsNodeOfType(eELEMENT) test at the top of Match() instead of at each caller? Or do we have heavy-hitting callers that don't need to check? I guess AttributeChanged?
![]() |
Assignee | |
Comment 7•16 years ago
|
||
It's slower. As currently written, for textnodes we avoid:
1) Calling PopulateWith
2) Calling Match
3) Calling various virtual methods like GetChildCount and GetChildArray
because we do the IsNodeOfType check up front before even calling into PopulateWith. In fact, avoiding all those function calls is pretty much key to the speedup here; a lot of the time in this code is (still, and it was worse before) taken up by function-call overhead.
![]() |
Assignee | |
Comment 8•16 years ago
|
||
Pushed changeset 1bbcf1a4dc5 and changeset 9a15160ea01d to fix ensuing build bustage.
Status: NEW → RESOLVED
Closed: 16 years ago
Resolution: --- → FIXED
![]() |
Assignee | |
Comment 9•16 years ago
|
||
Backed out because it caused orange.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
![]() |
Assignee | |
Comment 10•16 years ago
|
||
Attachment #338128 -
Attachment is obsolete: true
![]() |
Assignee | |
Comment 11•16 years ago
|
||
Attachment #338341 -
Attachment is obsolete: true
![]() |
Assignee | |
Comment 12•16 years ago
|
||
Pushed changeset 4dfc88a342b2.
Status: REOPENED → RESOLVED
Closed: 16 years ago → 16 years ago
Resolution: --- → FIXED
Comment 13•16 years ago
|
||
Comment on attachment 338342 [details] [diff] [review]
Actually, this is the right diff
>+#ifdef DEBUG
>+ NS_ASSERTION(!debugMutationGuard.Mutated(0),
>+ "Unexpected mutations happened. Check your match function!");
>+#endif
Are content lists supposed to force generation of templated content? (This assertion fires because they do.)
![]() |
Assignee | |
Comment 14•16 years ago
|
||
1) Yes, I guess (no other way around it).
2) See bug 456653.
3) Lazy generation is going away in bug 450990, hopefully ASAP.
Depends on: 456653
Updated•6 years ago
|
Component: DOM → DOM: Core & HTML
You need to log in
before you can comment on or make changes to this bug.
Description
•