Bug 56770

Summary: Speed up HitTestResult
Product: WebKit Reporter: Geoff Pike <gpike>
Component: WebCore Misc.Assignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: ap, buildbot, commit-queue, dglazkov, webkit-ews
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Other   
OS: OS X 10.5   
Attachments:
Description Flags
Patch
none
Patch
none
Patch none

Geoff Pike
Reported 2011-03-21 14:18:46 PDT
Speed up HitTestResult
Attachments
Patch (7.26 KB, patch)
2011-03-21 14:19 PDT, Geoff Pike
no flags
Patch (7.43 KB, patch)
2011-03-21 15:15 PDT, Geoff Pike
no flags
Patch (7.76 KB, patch)
2011-03-22 14:34 PDT, Geoff Pike
no flags
Geoff Pike
Comment 1 2011-03-21 14:19:25 PDT
Early Warning System Bot
Comment 2 2011-03-21 14:36:00 PDT
Dimitri Glazkov (Google)
Comment 3 2011-03-21 14:36:16 PDT
Comment on attachment 86365 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=86365&action=review Looks reasonable, aside from a style nitpick. > Source/WebCore/rendering/HitTestResult.cpp:583 > + for (NodeSet::const_iterator it = other.m_rectBasedTestResult->begin(), > + last = other.m_rectBasedTestResult->end(); The indent is weird here. Come to the dark side... Put it on one line :)
Build Bot
Comment 4 2011-03-21 14:39:25 PDT
Dimitri Glazkov (Google)
Comment 5 2011-03-21 14:42:29 PDT
... and the bot gods look angry.
Geoff Pike
Comment 6 2011-03-21 15:15:42 PDT
Geoff Pike
Comment 7 2011-03-21 15:21:14 PDT
Thanks for the review! OK, I put the "for (...)" on one line. The bot anger was because some compilers are not optimizing "if (!x) { if (x) ...; y; }" to "if (!x) y;" before instantiating templates. That should be fixed by moving the offending code to the .cpp file where it has the definition of WebCore::Node available.
Dimitri Glazkov (Google)
Comment 8 2011-03-21 16:22:51 PDT
Comment on attachment 86372 [details] Patch let's give this puppy a whirl.
Darin Adler
Comment 9 2011-03-21 16:37:47 PDT
Comment on attachment 86372 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=86372&action=review > Source/WebCore/rendering/HitTestResult.cpp:108 > + m_rectBasedTestResult.set(other.m_rectBasedTestResult ? new NodeSet(*other.m_rectBasedTestResult) : 0); Please use adoptPtr rather than the obsolete set. > Source/WebCore/rendering/HitTestResult.cpp:134 > + m_rectBasedTestResult.set(other.m_rectBasedTestResult ? new NodeSet(*other.m_rectBasedTestResult) : 0); Please use adoptPtr rather than the obsolete set. > Source/WebCore/rendering/HitTestResult.cpp:562 > - m_rectBasedTestResult.add(node); > + getOrCreateNodeSet().add(node); I think the function could just be named nodeSet(). But also, before it was named based on its purpose and now you named it based on its data type. > Source/WebCore/rendering/HitTestResult.cpp:602 > + m_rectBasedTestResult.set(new NodeSet()); Please use adoptPtr instead of set. No need for the parentheses after NodeSet. > Source/WebCore/rendering/HitTestResult.h:123 > + const NodeSet& rectBasedTestResult() { return getOrCreateNodeSet(); } The old function was const, but your new function is not. But it should be. > Source/WebCore/rendering/HitTestResult.h:127 > + NodeSet& getOrCreateNodeSet(); This should be const. > Source/WebCore/rendering/HitTestResult.h:146 > + OwnPtr<NodeSet> m_rectBasedTestResult; This should be mutable.
Dimitri Glazkov (Google)
Comment 10 2011-03-21 16:44:51 PDT
Comment on attachment 86372 [details] Patch darin has good comments, as always.
Geoff Pike
Comment 11 2011-03-21 17:06:07 PDT
Thanks for the review! > > Source/WebCore/rendering/HitTestResult.h:123 > > + const NodeSet& rectBasedTestResult() { return getOrCreateNodeSet(); } > > The old function was const, but your new function is not. But it should be. I considered that option but was concerned about thread safety. If a method is const then I would expect it to be safe to call without locking. If I take your suggestion should I also add an explanatory comment?
Alexey Proskuryakov
Comment 12 2011-03-22 09:58:15 PDT
There is no expectation that const methods in WebKit are safe to call from any thread. We actually prefer designs where a given object only has its methods called from a single thread. Besides, nothing in DOM or layout code is thread safe.
Geoff Pike
Comment 13 2011-03-22 14:34:44 PDT
Alexey Proskuryakov
Comment 14 2011-03-22 14:46:53 PDT
+ cost of HitTestResult(IntPoint()) in EventHandler::mouseMoved() + from ~1700 cycles to ~300 cycles. What are the reasons to believe that it's worth making the code more complicated for this? The improvement is on microsecond scale. Historically, we had a lot of success making many 1% performance improvements, but it's not obvious if there is any scenario where this would provide 1%.
Geoff Pike
Comment 15 2011-03-22 16:05:21 PDT
Thanks for the review! I agree this is not an earth-shattering improvement. I found it when informal testing and instrumentation suggested that this code path is high on the list of things that drive memory allocation and deallocation. And it's worse than the typical allocation, because it allocates several kilobytes and memsets the whole thing and then, typically, uses none of it. I estimate that the change can save a few ms of CPU per wall-clock second when the mouse is moving. It may be useful under other circumstances as well, I'm not sure. If you want more information or would like to suggest other areas where performance tuning would be more fruitful, please let me know.
Alexey Proskuryakov
Comment 16 2011-03-22 16:11:53 PDT
> I estimate that the change can save a few ms of CPU per wall-clock second when the mouse is moving. That sounds more substantial than what I mentioned. Could you please share your calculation?
Geoff Pike
Comment 17 2011-03-22 23:11:20 PDT
The savings per HitTestResult object is say 1400 cycles plus a bit more for the destructor. Call it .5 to 1 us. If you start Chrome and rapidly click links for 20 seconds and quit, several thousand HitTestResult objects are created and destroyed per second. That suggests a realistic peak savings of a few CPU ms per second when the mouse is moving. Of course, most of the time it's not. Even so, it's not that ugly a change for the benefit it provides.
Geoff Pike
Comment 18 2011-03-25 16:29:17 PDT
This still looks like a good change to me :) Alexey, your thoughts?
Dimitri Glazkov (Google)
Comment 19 2011-03-29 12:39:32 PDT
Comment on attachment 86507 [details] Patch This looks good now.
WebKit Commit Bot
Comment 20 2011-03-29 15:47:27 PDT
Comment on attachment 86507 [details] Patch Clearing flags on attachment: 86507 Committed r82340: <http://trac.webkit.org/changeset/82340>
WebKit Commit Bot
Comment 21 2011-03-29 15:47:31 PDT
All reviewed patches have been landed. Closing bug.
Note You need to log in before you can comment on or make changes to this bug.