Bug 87863 - Web Inspector: speed up _calculateRetainedSizes function
Summary: Web Inspector: speed up _calculateRetainedSizes function
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Inspector (Deprecated) (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Normal
Assignee: Alexei Filippov
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-05-30 09:41 PDT by Alexei Filippov
Modified: 2012-06-04 05:38 PDT (History)
10 users (show)

See Also:


Attachments
Patch (4.17 KB, patch)
2012-05-30 10:00 PDT, Alexei Filippov
no flags Details | Formatted Diff | Diff
Patch (3.60 KB, patch)
2012-05-31 05:30 PDT, Alexei Filippov
no flags Details | Formatted Diff | Diff
Patch (12.73 KB, patch)
2012-05-31 06:42 PDT, Alexei Filippov
no flags Details | Formatted Diff | Diff
Patch (13.28 KB, patch)
2012-06-01 05:41 PDT, Alexei Filippov
no flags Details | Formatted Diff | Diff
Patch (13.29 KB, patch)
2012-06-01 05:54 PDT, Alexei Filippov
no flags Details | Formatted Diff | Diff
Patch (13.34 KB, patch)
2012-06-01 06:04 PDT, Alexei Filippov
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Alexei Filippov 2012-05-30 09:41:32 PDT
Rewrite the algorithm to be O(n) instead of O(n*log(n)).

Before:
RESULT heap-snapshot: _calculateRetainedSizes= 86 ms

After:
RESULT heap-snapshot: _calculateRetainedSizes= 31 ms
Comment 1 Alexei Filippov 2012-05-30 10:00:05 PDT
Created attachment 144845 [details]
Patch
Comment 2 Yury Semikhatsky 2012-05-31 00:59:00 PDT
Comment on attachment 144845 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=144845&action=review

> Source/WebCore/inspector/front-end/HeapSnapshot.js:1253
> +        var nodesSelfSize = this._nodes.subarray(this._nodeSelfSizeOffset);

You don't need subarray here, adding this._nodeSelfSizeOffset would probably be more clear to the reader.

> Source/WebCore/inspector/front-end/HeapSnapshot.js:1263
> +        nodeStack[nodeStackTop] = rootNodeOrdinal;

Now that we anyways have postorder index we could go though it and update each nodes retained size sequentially. This way you wouldn't need this stack. WDYT?
Comment 3 Yury Semikhatsky 2012-05-31 00:59:17 PDT
(In reply to comment #0)
> Rewrite the algorithm to be O(n) instead of O(n*log(n)).
> 
> Before:
> RESULT heap-snapshot: _calculateRetainedSizes= 86 ms
> 
> After:
> RESULT heap-snapshot: _calculateRetainedSizes= 31 ms

What's the point in optimizing this given that it is such a small fraction of the overall time?
Comment 4 Yury Semikhatsky 2012-05-31 04:50:35 PDT
Comment on attachment 144845 [details]
Patch

Clearing r? until the comments are addressed.
Comment 5 Alexei Filippov 2012-05-31 05:25:51 PDT
(In reply to comment #2)
> (From update of attachment 144845 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=144845&action=review
> 
> > Source/WebCore/inspector/front-end/HeapSnapshot.js:1253
> > +        var nodesSelfSize = this._nodes.subarray(this._nodeSelfSizeOffset);
> 
> You don't need subarray here, adding this._nodeSelfSizeOffset would probably be more clear to the reader.

I've done that to eliminate extra addition from the loop. But if you think the code became too complicated, I'll change it back.

> 
> > Source/WebCore/inspector/front-end/HeapSnapshot.js:1263
> > +        nodeStack[nodeStackTop] = rootNodeOrdinal;
> 
> Now that we anyways have postorder index we could go though it and update each nodes retained size sequentially. This way you wouldn't need this stack. WDYT?

Cool idea. Done that. The time has reduced to 10ms.

(In reply to comment #3)
> (In reply to comment #0)
> > Rewrite the algorithm to be O(n) instead of O(n*log(n)).
> > 
> > Before:
> > RESULT heap-snapshot: _calculateRetainedSizes= 86 ms
> > 
> > After:
> > RESULT heap-snapshot: _calculateRetainedSizes= 31 ms
> 
> What's the point in optimizing this given that it is such a small fraction of the overall time?

This fraction is small for this particular performance test. You know the current algorithm has O(n*n) for the worst case (e.g. a linked list structure).
I checked it on a worst case test having 50k objects. The time it spends in this function has dropped from 10000ms to 2ms.
Comment 6 Yury Semikhatsky 2012-05-31 05:30:39 PDT
(In reply to comment #5)
> (In reply to comment #2)
> > (From update of attachment 144845 [details] [details])
> > View in context: https://bugs.webkit.org/attachment.cgi?id=144845&action=review
> > 
> > > Source/WebCore/inspector/front-end/HeapSnapshot.js:1253
> > > +        var nodesSelfSize = this._nodes.subarray(this._nodeSelfSizeOffset);
> > 
> > You don't need subarray here, adding this._nodeSelfSizeOffset would probably be more clear to the reader.
> 
> I've done that to eliminate extra addition from the loop. But if you think the code became too complicated, I'll change it back.
> 
> > 
> > > Source/WebCore/inspector/front-end/HeapSnapshot.js:1263
> > > +        nodeStack[nodeStackTop] = rootNodeOrdinal;
> > 
> > Now that we anyways have postorder index we could go though it and update each nodes retained size sequentially. This way you wouldn't need this stack. WDYT?
> 
> Cool idea. Done that. The time has reduced to 10ms.
> 
Mind uploading new patch?

> (In reply to comment #3)
> > (In reply to comment #0)
> > > Rewrite the algorithm to be O(n) instead of O(n*log(n)).
> > > 
> > > Before:
> > > RESULT heap-snapshot: _calculateRetainedSizes= 86 ms
> > > 
> > > After:
> > > RESULT heap-snapshot: _calculateRetainedSizes= 31 ms
> > 
> > What's the point in optimizing this given that it is such a small fraction of the overall time?
> 
> This fraction is small for this particular performance test. You know the current algorithm has O(n*n) for the worst case (e.g. a linked list structure).
> I checked it on a worst case test having 50k objects. The time it spends in this function has dropped from 10000ms to 2ms.
Can you convert that into a layout test/performance test?
Comment 7 Alexei Filippov 2012-05-31 05:30:50 PDT
Created attachment 145061 [details]
Patch
Comment 8 Alexei Filippov 2012-05-31 06:42:55 PDT
Created attachment 145079 [details]
Patch
Comment 9 Alexei Filippov 2012-05-31 06:43:17 PDT
Added the performance test.
Comment 10 Yury Semikhatsky 2012-05-31 06:52:57 PDT
Comment on attachment 145079 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=145079&action=review

> PerformanceTests/inspector/performance-test.js:148
> +    InspectorTest.measureFunction(WebInspector.HeapSnapshot.prototype, "_buildRetainers");

This file is used not only by profiler.
Comment 11 Ilya Tikhonovsky 2012-05-31 06:55:25 PDT
View in context: https://bugs.webkit.org/attachment.cgi?id=145079&action=review

> PerformanceTests/inspector/performance-test.js:211
> +            timer.done("heap-snapshot");

heap-snapshot is a page name. You have to calculate it from the url or transfer it as an argument.
Comment 12 Alexei Filippov 2012-06-01 05:41:25 PDT
Created attachment 145276 [details]
Patch
Comment 13 Yury Semikhatsky 2012-06-01 05:50:05 PDT
Comment on attachment 145276 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=145276&action=review

> PerformanceTests/inspector/heap-performance-test.js:1
> +function test()

heap-performance-test.js -> heap-profiler-performance-test.js or heap-snapshot-performance-test.js
Comment 14 Alexei Filippov 2012-06-01 05:54:23 PDT
Created attachment 145280 [details]
Patch
Comment 15 Ilya Tikhonovsky 2012-06-01 05:57:55 PDT
Comment on attachment 145280 [details]
Patch

looks good to me
Comment 16 Alexei Filippov 2012-06-01 06:04:11 PDT
Created attachment 145283 [details]
Patch
Comment 17 WebKit Review Bot 2012-06-04 05:28:54 PDT
Comment on attachment 145283 [details]
Patch

Rejecting attachment 145283 [details] from commit-queue.

alexeif@chromium.org does not have committer permissions according to http://trac.webkit.org/browser/trunk/Tools/Scripts/webkitpy/common/config/committers.py.

- If you do not have committer rights please read http://webkit.org/coding/contributing.html for instructions on how to use bugzilla flags.

- If you have committer rights please correct the error in Tools/Scripts/webkitpy/common/config/committers.py by adding yourself to the file (no review needed).  The commit-queue restarts itself every 2 hours.  After restart the commit-queue will correctly respect your committer rights.
Comment 18 Ilya Tikhonovsky 2012-06-04 05:38:45 PDT
Comment on attachment 145283 [details]
Patch

Clearing flags on attachment: 145283

Committed r119389: <http://trac.webkit.org/changeset/119389>
Comment 19 Ilya Tikhonovsky 2012-06-04 05:38:55 PDT
All reviewed patches have been landed.  Closing bug.