Closed
Bug 270257
Opened 21 years ago
Closed 21 years ago
nsSVGElement::SetParent is expensive
Categories
(Core :: SVG, defect)
Tracking
()
RESOLVED
FIXED
People
(Reporter: bzbarsky, Assigned: jwatt)
References
Details
(Keywords: perf)
Attachments
(2 files, 5 obsolete files)
375 bytes,
image/svg+xml
|
Details | |
1.48 KB,
patch
|
alex
:
review+
|
Details | Diff | Splinter Review |
This seems to send various notifications to some sorts of listeners on the
nsSVGLength attributes (from nsSVGRectElement::ParentChainChanged()).
Can those be lazy, somehow? Esp. in light of bug 270255...
All that's happening here is creating an SVG node, setting 5 attrs, and
inserting into the document; it looks like we do a fair amount of duplicated
work during that process.
one thing that is expensive is that we end up with a callchain like this:
SetContext->DidModify->NotifyObservers->DidModifySVGObservable->NotifyObserves->
nsSVGElement::DidModifySVGObservale->nsSVGElement::SetAttrAndNotify
In other words, we end up setting as reall attributes all 'mapped attributes'
that we call SetContext on.
This is both expensive and wrong since those attributes shouldn't show up in the
DOM unless explicitly set.
![]() |
Assignee | |
Comment 2•21 years ago
|
||
Actually I don't think we should call Will/DidModify in nsSVGLength::SetContext
at all. To expand the call chain Jonas mentioned, the stack that results in
SetAttrAndNotify being called when inserting an nsSVGRect element into a
document is as follows.
Object Method
------ ------
nsSVGRect nsSVGElement::SetAttrAndNotify()
nsSVGRect nsSVGElement::DidModifySVGObservable()
nsSVGAnimatedLength nsSVGValue::NotifyObservers()
nsSVGAnimatedLength nsSVGValue::DidModify()
nsSVGAnimatedLength nsSVGAnimatedLength::DidModifySVGObservable()
nsSVGLength nsSVGValue::NotifyObservers()
nsSVGLength nsSVGValue::DidModify()
nsSVGLength nsSVGLength::SetContext()
nsSVGRect nsSVGRectElement::ParentChainChanged()
nsSVGRect nsSVGElement::SetParent()
I don't think we should call Will/DidModify for changes further *up* a parent
chain - only for changes further *down* it. When one object watches another, it
should only expect to be notified if that object or one of its decendents
changes. I don't think nsSVGLength::SetContext should be an exception to this
rule. The nsSVGLength object itself doesn't actually change as a result of one
of its ancestors being inserted into a new coordinate "context".
Whenever SetContext is called, it's because the nsSVGLength or one of it's
ancestors is being inserted into an SVG document fragment, or because it is
being inserted/removed from an nsSVGLengthList object. The function that carries
out the insertion should make sure any necessary notifications are sent out.
Assignee: general → jonathan.watt
![]() |
Assignee | |
Comment 3•21 years ago
|
||
![]() |
Assignee | |
Comment 4•21 years ago
|
||
Comment on attachment 168073 [details] [diff] [review]
don't Will/DidModify in SetContext
Alex, can you review please.
Attachment #168073 -
Flags: review?(alex)
![]() |
||
Comment 5•21 years ago
|
||
Comment on attachment 168073 [details] [diff] [review]
don't Will/DidModify in SetContext
As discussed on irc, this won't work.
For percentage lengths, the 'real' user-unit value is determined by looking at
the context, and most observers expect to be informed of a change in the 'real'
value of a length.
The quick and dirty workaround would be to add a
'we-are-changing-the-context-not-the-actual-specified-value'-flag to
WillModify/DidModify.
Attachment #168073 -
Flags: review?(alex) → review-
Do we really need to notify the frame about parentchanges? It seems like
whenever the parent is changed we will move the node out of the old position in
the tree and into the new. During the moving out isn't the frame get destroyed,
and then recreated once the element is in the new position?
![]() |
||
Comment 7•21 years ago
|
||
(In reply to comment #6)
> Do we really need to notify the frame about parentchanges? It seems like
> whenever the parent is changed we will move the node out of the old position in
> the tree and into the new. During the moving out isn't the frame get destroyed,
> and then recreated once the element is in the new position?
Good point. Maybe the patch is ok after all.
![]() |
||
Updated•21 years ago
|
Attachment #168073 -
Flags: review- → review+
Checking in nsSVGLength.cpp;
/cvsroot/mozilla/content/svg/content/src/nsSVGLength.cpp,v <-- nsSVGLength.cpp
new revision: 1.14; previous revision: 1.13
done
![]() |
||
Comment 10•21 years ago
|
||
Backed out per irc conversation.
![]() |
Assignee | |
Comment 11•21 years ago
|
||
I've opened bug 274886 to address the issue of the SetAttrAndNotify call
separately since it no longer looks as if it will be fixed by removing the
WillModify/DidModify calls.
One thing we should do is check if mSpecifiedUnitType ==
SVG_LENGTHTYPE_PERCENTAGE before calling WillModify and DidModify in SetContext.
That doesn't make the notifications lazy, but it will eliminate a lot of
unnecessary notifications.
![]() |
Assignee | |
Comment 12•21 years ago
|
||
Tim, can you check this doesn't crash you and review please?
![]() |
Assignee | |
Updated•21 years ago
|
Attachment #168073 -
Attachment is obsolete: true
Attachment #168863 -
Flags: review?(tor)
![]() |
Assignee | |
Updated•21 years ago
|
Attachment #168863 -
Flags: review?(tor)
![]() |
Assignee | |
Comment 13•21 years ago
|
||
of course all lengths that aren't already in user units need a context to
determine what their user unit value is - thanks alex!
![]() |
Assignee | |
Updated•21 years ago
|
Attachment #168863 -
Attachment is obsolete: true
![]() |
Assignee | |
Comment 14•21 years ago
|
||
wrong file, sorry for the spam :-(
Attachment #169220 -
Attachment is obsolete: true
![]() |
Assignee | |
Comment 15•21 years ago
|
||
:-/ Win98 seems to have a stupid "feature" where it opens text files under
their DOS name. Again, sorry for the spam, here's the patch with the changes.
Attachment #169221 -
Attachment is obsolete: true
![]() |
Assignee | |
Comment 16•21 years ago
|
||
I'm not sure about making things lazy, but how about we only notify our
observers when necessary?
bz: I would be interested to know if the checkin to fix the problem whereby
SetAttrAndNotify was always being called has helped performance any.
![]() |
Assignee | |
Updated•21 years ago
|
Attachment #169224 -
Attachment is obsolete: true
Attachment #171842 -
Flags: review?(tor)
![]() |
||
Comment 17•21 years ago
|
||
Comment on attachment 171842 [details] [diff] [review]
only notify when necessary
r=afri
Attachment #171842 -
Flags: review?(tor) → review+
![]() |
Assignee | |
Comment 18•21 years ago
|
||
Comment on attachment 171842 [details] [diff] [review]
only notify when necessary
Thanks Alex! Before this patch get's checked in I'd like to make sure that Tim
doesn't crash with it applied. Tim?
![]() |
||
Comment 19•21 years ago
|
||
My testcases seem to work fine with the patch now.
![]() |
||
Comment 20•21 years ago
|
||
Checked in.
![]() |
Assignee | |
Comment 21•21 years ago
|
||
Boris, can I close this bug? If you can think of anything specific we could do
to make nsSVGElement::SetParent more efficient then I'll have a go at it here.
If you have any general problems with the notification system I think we should
open a separate bug.
![]() |
Reporter | |
Comment 22•21 years ago
|
||
Feel free to close it, yes. I'll profile the testcase in bug 261974 with this
patch and file new bugs as needed....
![]() |
Assignee | |
Updated•21 years ago
|
Status: NEW → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
![]() |
Reporter | |
Comment 23•21 years ago
|
||
OK. With a build from MOZ_CO_DATE="Thu Jan 20 22:08:11 CST 2005" the time spent
in SetParent is less than 0.6% of the total time spent on the testcase in bug
261974. So looks like this helped, at least for those attributes!
![]() |
Assignee | |
Comment 24•21 years ago
|
||
bz, what do you get if you change all dimensions into millimeters:
el.setAttribute("x", Math.random()*100 + "mm");
el.setAttribute("y", Math.random()*100 + "mm");
el.setAttribute("width", "1mm");
el.setAttribute("height", "1mm");
That will give you poorer results. What I'd be interested to know though, is how
the results from that compair to your original results.
![]() |
Reporter | |
Comment 25•21 years ago
|
||
Using "mm" makes the time in SetParent about double. I don't recall how this
compares to what I used to see... I suppose I could back this patch out (just
the last one, right?) and retest without it.
![]() |
Assignee | |
Comment 26•21 years ago
|
||
No, testing using "mm" should give you virtually the same results as with the
patch backed out. The patch only made things faster for unitless and "px" lengths.
What I was interested to know was how much the patch for bug 274886 has helped.
It essentially stopped us from calling SetAttrAndNotify, and I was interested to
know how much time had been spent in that function. Unfortunately, the patch to
that bug was rather more wide reaching (it touched 51 files) so if you don't
remember what you were getting before then I guess we'll never know. :-)
![]() |
Reporter | |
Comment 27•21 years ago
|
||
Well... Given that I filed this bug, the number before was at least in the 5%
ballpark, and I seem to recall it being more like 10-15%. I wasn't going to say
it because this patch didn't seem to help that much, but yes, the patch for bug
274886 would have helped a good bit.
![]() |
Assignee | |
Comment 28•21 years ago
|
||
Great, that's what I wanted to know. BTW, when you said the time *in*, did you
mean the time *under* (by which I mean the time spent from when SetParent
starts, to when it ends).
![]() |
Reporter | |
Comment 29•21 years ago
|
||
Yes, all times are under. Time in the function itself is pretty negligible. ;)
You need to log in
before you can comment on or make changes to this bug.
Description
•