Use bulk sending APIs to transmit the profile from the perf actor, when sending the profile from Android to the desktop browser (startBulkSend, startBulkRequest, copyFrom)
Categories
(DevTools :: Performance Tools (Profiler/Timeline), enhancement, P3)
Tracking
(firefox140 fixed)
| Tracking | Status | |
|---|---|---|
| firefox140 | --- | fixed |
People
(Reporter: gregtatum, Assigned: julienw)
References
(Blocks 2 open bugs)
Details
(Whiteboard: [fxp-profiler])
Attachments
(5 files, 5 obsolete files)
Right now a JSON profile is sent over the RDP. It seems that array buffers are now supports for some instances. We should see if we can make it faster when running locally by getting the gzipped version sent over RDP, rather than the full Profile.
The two browser calls are:
- Services.profiler.getProfileDataAsGzippedArrayBuffer
- Services.profiler.getProfileDataAsync
Comment 1•4 years ago
|
||
(In reply to Greg Tatum [:gregtatum] from comment #0)
It seems that array buffers are now supports for some instances.
Nicolas, do you know more details about this? Can array buffers be sent over the devtools protocol these days?
Comment 2•4 years ago
|
||
(In reply to Markus Stange [:mstange] from comment #1)
(In reply to Greg Tatum [:gregtatum] from comment #0)
It seems that array buffers are now supports for some instances.
Nicolas, do you know more details about this? Can array buffers be sent over the devtools protocol these days?
So I don't know much about this, but I don't think we can send ArrayBuffers through RDP.
Looking at the code, it seems that we're interested in this function: https://searchfox.org/mozilla-central/rev/5227b2bd674d49c0eba365a709d3fb341534f361/devtools/shared/performance-new/gecko-profiler-interface.js#147-186
It's in devtools/shared which means it can be accessed from the DevTools client and the DevTools server.
So what could be done is to detect when we're not debugging a remote server, and in such case, directly call getProfileAndStopProfiler from the client (from here I guess https://searchfox.org/mozilla-central/rev/5227b2bd674d49c0eba365a709d3fb341534f361/devtools/client/performance-new/store/actions.js#211)
That's something we thought at some point for screenshots, where a long time is spent stringifying data so we can send them through RDP, although we could directly access them when we're not debugging remotely.
Comment 3•4 years ago
|
||
Thanks! It's somewhat unsatisfying to leave remote targets on the slow path, though. And it sounds like the ability to remotely transmit array buffers efficiently would be useful in other places, too. I can file a bug about adding this capability; do you know who'd be the right person to assess the feasibility of this?
Comment 4•4 years ago
|
||
(In reply to Markus Stange [:mstange] from comment #3)
Thanks! It's somewhat unsatisfying to leave remote targets on the slow path, though. And it sounds like the ability to remotely transmit array buffers efficiently would be useful in other places, too. I can file a bug about adding this capability; do you know who'd be the right person to assess the feasibility of this?
ochameau and jdescottes should know more than me about the different DevTools transport layers
Comment 5•4 years ago
|
||
Yes, there is a binary escape path in RDP.
Unfortunately, it isn't super documented, nor used.
There is this one usage you can take as example, the memory profile generated by the memory panel.
Server side code:
https://searchfox.org/mozilla-central/rev/c0fc8c4852e927b0ae75d893d35772b8c60ee06b/devtools/server/actors/heap-snapshot-file.js#57-82
On this side, the key here is to use this.conn.startBulkSend and bulk.copyFrom.
Client side code:
https://searchfox.org/mozilla-central/rev/c0fc8c4852e927b0ae75d893d35772b8c60ee06b/devtools/client/fronts/memory.js#82-113
Note that this client code should be using DevToolsClient.startBulkRequest. (no idea why it isn't)
On this side, it is about using client.startBulkRequest and const { copyTo } = await request;
This is completely bypassing protocol.js, so there is nothing to declare in your spec (i.e. devtools/shared/spec).
Let me know if you need any more help with this.
Comment 6•4 years ago
|
||
Thanks a lot for these pointers! I will give this a try, once I get around to it.
Comment 7•4 years ago
•
|
||
Hah, funnily enough, the profiler is the primary use case in the description of bug 797639, which added the bulk writing capabilities 9 years ago. "Performance profiling" is also mentioned in a section about bulk data in the Remote Debugging Protocol documentation.
Updated•3 years ago
|
Comment 8•2 years ago
|
||
Morphing this bug to switch to the bulk sending APIs from comment 5. At the moment, we parse the profile into JSON on the Android device by using the API getProfileDataAsync here, and then we send the JS object across the pipe.
Updated•2 years ago
|
| Assignee | ||
Comment 9•6 months ago
|
||
(In reply to Alexandre Poirot [:ochameau] from comment #5)
Client side code:
https://searchfox.org/mozilla-central/rev/c0fc8c4852e927b0ae75d893d35772b8c60ee06b/devtools/client/fronts/memory.js#82-113
Note that this client code should be using DevToolsClient.startBulkRequest. (no idea why it isn't)
On this side, it is about usingclient.startBulkRequestandconst { copyTo } = await request;
I think it's not using startBulkRequest simply because the request itself isn't a "bulk" message, it only needs to send the snapshotId. I believe we have the same requirement to retrieve the profile data: we don't even have anything to send.
So I believe we don't need startBulkRequest either on the request side.
| Assignee | ||
Updated•6 months ago
|
| Assignee | ||
Comment 10•6 months ago
|
||
This also adds the trait to the Redux state, so that it can be retrieved
easily from anywhere.
(This may not be useful at the end, and I may remove it, but I'm keeping
it here in case it is)
| Assignee | ||
Comment 11•6 months ago
|
||
| Assignee | ||
Comment 12•6 months ago
|
||
| Assignee | ||
Comment 13•6 months ago
|
||
| Assignee | ||
Comment 14•6 months ago
|
||
| Assignee | ||
Comment 15•6 months ago
•
|
||
I tested capturing a profile with the Media preset while playing a video on Youtube on my own phone.
In all cases the new code was capturing the profile faster. As I expected the magnitude of the difference depends on the size of the profile.
Each time I give 2 numbers. The base time is when I click the "capture" button. The first measurement is when the button turns back to blue. The second measurement is when the profile opens in the browser. I think (but it would be good to check) that the first measurement is the capture time on device, while the second part is when the profile data is transfered (the second is is cumulative, so it includes also the capture).
For a 20-second profile:
old: 6s, then 14s
new: 5s, then 9s
For a 30-second profile:
old: 9s, then 20s
new: 5s, then 10s
For a 1-minute profile:
old: 16s then 1:03s
new: 14s then 24s
TBH I expected that the capture time could be longer, because now we're gzipping the profile on-device while previously we weren't doing that. But it looks like that gzipping it provides some improvement too. Or it's possible that it's just the matter of using a plain buffer rather than a JS object when handling the data on the devtools server layer.
Updated•6 months ago
|
| Assignee | ||
Comment 16•6 months ago
|
||
| Assignee | ||
Comment 17•6 months ago
|
||
| Assignee | ||
Comment 18•6 months ago
|
||
| Assignee | ||
Comment 19•6 months ago
|
||
Updated•6 months ago
|
Updated•6 months ago
|
Comment 20•6 months ago
|
||
Comment on attachment 9481569 [details]
WIP: Bug 1581963 - Improve DevtoolsUtils logging facility to include a timestamp r=ochameau
Revision D246970 was moved to bug 1963284. Setting attachment 9481569 [details] to obsolete.
Updated•5 months ago
|
Updated•5 months ago
|
Updated•5 months ago
|
Updated•5 months ago
|
Updated•5 months ago
|
Updated•5 months ago
|
Updated•5 months ago
|
Updated•5 months ago
|
Updated•5 months ago
|
Updated•5 months ago
|
| Assignee | ||
Comment 21•5 months ago
|
||
Comment 22•5 months ago
|
||
Comment 23•5 months ago
|
||
| bugherder | ||
https://hg.mozilla.org/mozilla-central/rev/0a64e67bffde
https://hg.mozilla.org/mozilla-central/rev/6a4878977fca
https://hg.mozilla.org/mozilla-central/rev/18010dd7c6a3
https://hg.mozilla.org/mozilla-central/rev/8e3df78fdb03
https://hg.mozilla.org/mozilla-central/rev/0d13792947ea
| Assignee | ||
Comment 24•5 months ago
•
|
||
In addition to the transfer from debuggee to debugger being faster, I think this work also made it so that the transfer from the firefox machinery to the firefox profiler UI is much faster: indeed the data is now an arraybuffer instead of a JS object, and as a result it's a transferable object instead of being structured cloned.
From my testing it seems to be reduced from 15 sec to 5 sec for a ~30MB profile.
The long part is now the symbolication part, esp libxul.so. But this happens also on desktop.
Updated•5 months ago
|
| Assignee | ||
Comment 25•5 months ago
|
||
Some numbers from capturing 1 minute with the media preset on youtube.
Before:
23.4 MB (gzipped) according to the text in the upload dialog.
- 12 sec to capture
- 18 sec to transfer
- 13 sec to open the UI
After:
27.6 MB (gzipped) according to the text in the upload dialog.
- 12 sec to capture
- near instant to transfer
- 6 sec to open the UI
Description
•