Closed
Bug 1363789
Opened 7 years ago
Closed 7 years ago
stylo: Use a 1-entry SmallVec in the selector maps to reduce allocations
Categories
(Core :: CSS Parsing and Computation, defect, P4)
Tracking
()
RESOLVED
FIXED
mozilla57
Tracking | Status | |
---|---|---|
firefox-esr52 | --- | unaffected |
firefox55 | --- | wontfix |
firefox56 | --- | wontfix |
firefox57 | --- | fixed |
People
(Reporter: bzbarsky, Assigned: bholley)
References
(Blocks 1 open bug)
Details
(Keywords: perf)
Attachments
(1 file)
4.41 KB,
patch
|
emilio
:
review+
|
Details | Diff | Splinter Review |
Looking at a profile of stylist::update for the myspace-orig testcase from bug 1358806, I'm seeing about 20% of the time under find_push and about half of that is malloc/realloc bits. find_push does this: map.entry(key).or_insert_with(Vec::new).push(value) where "map" is FnvHashMap<Str, Vec<V>, and this is going to heap-allocate storage for the vec the first time we end up inserting. For comparison, the equivalent Gecko data structure is: struct RuleHashTableEntry : public PLDHashEntryHdr { // Auto length 1, because we always have at least one entry in mRules. AutoTArray<RuleValue, 1> mRules; }; which avoids the extra allocation when there is only one rule targeting the id/class/tag involved. Might be worth checking what the actual lengths of these vecs end up being in practice; if "1" is a common length it might be worth doing something with an inline buffer. When I initially did the measurements in Gecko, back in 2011 or so, I got numbers along the lines of https://bugzilla.mozilla.org/show_bug.cgi?id=681755#c8 (the RuleHashTableEntry numbers are the ones relevant here). At the time, after loading a bunch of websites, about 60% of the arrays had length 1.
Reporter | ||
Comment 1•7 years ago
|
||
Oh, and per IRC discussion the allocs coming from the hashtable storage themselves are more or less unavoidable, and Gecko has those too. The hashtable starts off with no storage, then allocates a reasonable chunk all at once, then does doubling, so not much to improve there.
Assignee | ||
Comment 2•7 years ago
|
||
Nice idea! I will measure.
Assignee: nobody → bobbyholley
Priority: -- → P1
Reporter | ||
Comment 3•7 years ago
|
||
https://perf-html.io/public/87f8162a9d4d24e519628b481ff30bbbbf3345df/calltree/?callTreeFilters=prefix-01234567xEa9Ey1bcDYqD.ofKrxAexx3jDYo.qmL5xMrxMszMnzBazBbzBczD0zD1zLozL5zUtzUuzUvzV0zV1zV2zV3&thread=3 is the profile I'm looking at.
Assignee | ||
Comment 4•7 years ago
|
||
Have a patch, but the results on my usual testcases are inconclusive. 100x myspace doesn't benefit at all from this optimization, because every selector is duplicated. Going to try constructing a best-case and worst-case testcase.
Assignee | ||
Updated•7 years ago
|
Priority: P1 → P4
Assignee | ||
Comment 5•7 years ago
|
||
I measured this on amazon, looking at the interval between navigation start and first non-blank paint (what tp6 measures). The numbers are noisy, but I think it definitely improve things. Without this patch I get times in the range of 29-40, and with this patch I get times in the range of 23-32. It's simple enough, so I think it's worth getting it into the tree.
Blocks: 1386045
Summary: stylo: stylist update spends a bunch of time in malloc → stylo: Use a 1-entry SmallVec in the selector maps to reduce allocations
Assignee | ||
Comment 6•7 years ago
|
||
MozReview-Commit-ID: 1JPkVxs3cdP
Attachment #8894243 -
Flags: review?(emilio+bugs)
Assignee | ||
Comment 7•7 years ago
|
||
(In reply to Bobby Holley (:bholley) (busy with Stylo) from comment #5) > I measured this on amazon, looking at the interval between navigation start > and first non-blank paint (what tp6 measures). Specifically, looking at the work spent in Servo_StyleSet_* in this interval.
Assignee | ||
Comment 8•7 years ago
|
||
https://treeherder.mozilla.org/#/jobs?repo=try&revision=c8c473154198a9d362613120b8a4363372bf8b80
Comment 9•7 years ago
|
||
Comment on attachment 8894243 [details] [diff] [review] Use a 1-entry smallvec in the selector maps. v1 Review of attachment 8894243 [details] [diff] [review]: ----------------------------------------------------------------- r=me, with the comment. I wonder if the invalidation stuff should also use them... Seems likely it'd also benefit from it. ::: servo/components/style/selector_map.rs @@ +52,5 @@ > /// TODO: Tune the initial capacity of the HashMap > #[derive(Debug)] > #[cfg_attr(feature = "servo", derive(HeapSizeOf))] > pub struct SelectorMap<T> { > /// A hash from an ID to rules which contain that ID selector. Please point here to the measurements done on both this bug and bug 681755.
Attachment #8894243 -
Flags: review?(emilio+bugs) → review+
Assignee | ||
Comment 10•7 years ago
|
||
(In reply to Emilio Cobos Álvarez [:emilio] from comment #9) > Comment on attachment 8894243 [details] [diff] [review] > Use a 1-entry smallvec in the selector maps. v1 > > Review of attachment 8894243 [details] [diff] [review]: > ----------------------------------------------------------------- > > r=me, with the comment. > > I wonder if the invalidation stuff should also use them... Seems likely it'd > also benefit from it. Hm, don't those use SelectorMaps under the hood? I don't see any other HashMaps mapping to Vecs in style/. > > ::: servo/components/style/selector_map.rs > @@ +52,5 @@ > > /// TODO: Tune the initial capacity of the HashMap > > #[derive(Debug)] > > #[cfg_attr(feature = "servo", derive(HeapSizeOf))] > > pub struct SelectorMap<T> { > > /// A hash from an ID to rules which contain that ID selector. > > Please point here to the measurements done on both this bug and bug 681755. Done.
Flags: needinfo?(emilio+bugs)
Assignee | ||
Comment 11•7 years ago
|
||
https://github.com/servo/servo/pull/17988
Comment 12•7 years ago
|
||
Err, right, nvm, they use SelectorMap already.
Flags: needinfo?(emilio+bugs)
Assignee | ||
Comment 13•7 years ago
|
||
https://hg.mozilla.org/integration/autoland/rev/179f972c8e053a35b3bc5cffc32523451658b3b0
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Updated•7 years ago
|
status-firefox57:
--- → fixed
Target Milestone: --- → mozilla57
Updated•7 years ago
|
status-firefox55:
--- → wontfix
status-firefox56:
--- → wontfix
status-firefox-esr52:
--- → unaffected
You need to log in
before you can comment on or make changes to this bug.
Description
•