Closed
Bug 746439
Opened 12 years ago
Closed 6 years ago
Contacts API: profile performance
Categories
(Core Graveyard :: DOM: Contacts, defect, P2)
Core Graveyard
DOM: Contacts
Tracking
(blocking-kilimanjaro:+, blocking-basecamp:-)
RESOLVED
WONTFIX
People
(Reporter: gwagner, Assigned: jrmuizel)
References
Details
(Whiteboard: [LOE:M])
Attachments
(1 file)
3.00 MB,
application/octet-stream
|
Details |
We want to be able to retrieve contacts in chunks.
Reporter | ||
Updated•12 years ago
|
Blocks: b2g-contact
Updated•12 years ago
|
OS: Mac OS X → All
Hardware: x86 → All
Version: unspecified → Trunk
Updated•12 years ago
|
blocking-basecamp: --- → ?
Reporter | ||
Comment 1•12 years ago
|
||
We still have to figure out how much of an improvement we can get with such a patch. The problem is that in order to return a sorted list of contacts, we still have to retrieve all contacts from the DB and sort them. The only performance improvement that this bug solves is the transfer of contacts from the parent to the child process. So we can transfer them in chunks instead of one list. We might want to set it blocking-basecamp if we find out that the transfer is a bottleneck.
Reporter | ||
Comment 2•12 years ago
|
||
Alberto feel free to post some performance numbers if you already did some measurements.
Assignee: nobody → anygregor
Comment 3•12 years ago
|
||
After some tests: It takes an average of 3500ms load the contacts app: Avg of 1700ms for getting the contacts from the DB. Here the request: var options = { sortBy: 'familyName', sortOrder: 'ascending' }; var request = navigator.mozContacts.find(options); It takes a while also painting the results, but after some improvements, I think I can reduce the time to 500ms (Avg of 1500ms right now). Not sure getting them in chuncks is going to help or not. Could you take a look where is the bottleneck in your side? Thanks.
Comment 4•12 years ago
|
||
How many contacts are those figures?
Comment 5•12 years ago
|
||
Sorry, forgot that: 500 contacts imported with UI test app Nice catch JM :) Regards
Comment 6•12 years ago
|
||
Blocking. And re-summarized to be non-proscriptive.
blocking-basecamp: ? → +
blocking-kilimanjaro: --- → +
Summary: Contacts API: Add pagination → Contacts API: improve performance
Step 1 here should be that we should profile the API calls and start figuring out where time is spent. We should do that before starting to guess at what the solution is.
Reporter | ||
Comment 8•12 years ago
|
||
I looked at the API side on otoro: It seems we spend most of the time transferring the contacts from the parent to the child process. I even see 1800msec for 500 contacts. Sorting takes about 180 msec.
Reporter | ||
Comment 9•12 years ago
|
||
I forgot to mention the total time for 500 contacts on otoro: Transfer from Parent to Child: 1923msec Total round-trip time: 2758msec
Reporter | ||
Comment 10•12 years ago
|
||
Jonas also asked for the time the getAll call takes: ca 300msec.
That almost defies belief! We could memcpy() 100MB in that time! Where's the 2.7s going?
Also, how much data are we transferring.
100mb ;)
Reporter | ||
Comment 14•12 years ago
|
||
The DB with some overhead is 3670016 bytes.
Comment 15•12 years ago
|
||
100mb for 500 contacts without photo? Is that correct?
Reporter | ||
Comment 16•12 years ago
|
||
(In reply to Alberto Pastor from comment #15) > 100mb for 500 contacts without photo? Is that correct? no. I hope not. otherwise bent has to fix it :)
Reporter | ||
Comment 17•12 years ago
|
||
I did some more measurements on the otoro device with 350 contacts. Timeline (in msec) starts when I send async find. Then I measure time to 1) receive message on parent side 2) before sorting (success callback of DB) 3) after sorting 4) receive in child 5) after success callback in JS empty DB, first call (opening the DB) 1) 24 2) 653 3) 653 4) 656 5) 657 empty DB, 2nd call after killing contacts app 1) 42 2) 427 3) 427 4) 434 5) 436 370 contacts, first call 1) 28 - 47 2) 1068 3) 1198 4) 1375 5) 2799 370 after killing contacts app 1) 21 2) 749 3) 882 4) 1071 5) 2505
Thanks! So it seems like we have two bottlenecks here. One is loading the data from IndexedDB, the other is that sending data from the child to the API takes a *huge* amount of time. What are we doing between 4 and 5? Are we just parsing the data from a string to an object graph using JSON.parse()? Or I guess we are having to create DOM objects for each contact and fill that with the appropriate data.
Reporter | ||
Comment 19•12 years ago
|
||
(In reply to Jonas Sicking (:sicking) from comment #18) > > What are we doing between 4 and 5? Are we just parsing the data from a > string to an object graph using JSON.parse()? Or I guess we are having to > create DOM objects for each contact and fill that with the appropriate data. That also includes the time we spend in the callback.
Ugh, ok, so then the last number does say that much regarding the performance of the API :(. So it seems that we then have one unknown, which is how much time we spend in the API between 4 and 5, and then the IndexedDB performance. So likely we should start profiling the IndexedDB implementation as well.
Comment 21•12 years ago
|
||
Jeff may be able to help here with his mad profiling skillz.
Assignee | ||
Comment 22•12 years ago
|
||
I'm profiling on a Mac now and so don't have working leaf symbols but this profile should give a bit of an idea of what's going on (at least for the last 3 seconds): http://people.mozilla.com/~bgirard/cleopatra/?report=3d9474d4a82e5351b8879b01d7f06457c9ccce13
Assignee | ||
Comment 23•12 years ago
|
||
I will still try to get something more useful.
Reporter | ||
Comment 24•12 years ago
|
||
(In reply to Jeff Muizelaar [:jrmuizel] from comment #22) > I'm profiling on a Mac now and so don't have working leaf symbols but this > profile should give a bit of an idea of what's going on (at least for the > last 3 seconds): > > http://people.mozilla.com/~bgirard/cleopatra/ > ?report=3d9474d4a82e5351b8879b01d7f06457c9ccce13 Are you profiling a b2g desktop build or a FF desktop build?
Two things are important when we're measuring here: 1. That we measure on an actual B2G device. IO performance is very different there than on desktop, so it'll matter a lot more than on desktop. 2. That we profile a testcase which doesn't do anything in the success callback. The main question in this bug is if we need to completely rewrite the API because it requires too much IO before delivering any results. So the first question is if we can make the actual API fast enough for what we need. What the app does is a secondary concern and easier to fix.
Assignee | ||
Comment 26•12 years ago
|
||
(In reply to Jeff Muizelaar [:jrmuizel] from comment #22) > I'm profiling on a Mac now and so don't have working leaf symbols but this > profile should give a bit of an idea of what's going on (at least for the > last 3 seconds): > > http://people.mozilla.com/~bgirard/cleopatra/ > ?report=3d9474d4a82e5351b8879b01d7f06457c9ccce13 Sorry this wasn't clear: This is a profile of b2g on a Nexus S using a Mac instead of my usual desktop Linux machine.
Assignee | ||
Comment 27•12 years ago
|
||
(In reply to Jonas Sicking (:sicking) from comment #25) > 2. That we profile a testcase which doesn't do anything in the success > callback. The main question in this bug is if we need to completely rewrite > the API because it requires too much IO before delivering any results. So > the first question is if we can make the actual API fast enough for what we > need. What the app does is a secondary concern and easier to fix. It would be lovely if someone could write that test case.
Reporter | ||
Comment 28•12 years ago
|
||
Contacts DB with 350 entries.
Reporter | ||
Comment 29•12 years ago
|
||
Hi Jeff, I created a testcase in gaia. You can just download https://github.com/gregorwagner/gaia/tree/perfTest I added a button to UI Tests->Contacts tests->Get all contacts. You can download the DB with 350 contacts and push it to /data/local/indexedDB/chrome on your device
Assignee | ||
Comment 30•12 years ago
|
||
Here's a proper profile of Contacts startup on the b2g device: http://people.mozilla.com/~bgirard/cleopatra/?report=bcab890025670003ebb41473801b1dffbccdbf78 I'll profile the testcase next.
Assignee | ||
Comment 31•12 years ago
|
||
Here's a profile of the testcase: http://people.mozilla.com/~bgirard/cleopatra/?report=13281a18cbe5c7ffcd16ea9e6c113d3b360d2f60
Almost all the time is spent in "syscall". Any ideas what that is? Could that be the IO caused by IndexedDB? But if so I'm surprised that various sqlite signatures aren't showing up. Note that all IndexedDB IO happens on background threads in the parent process.
Assignee | ||
Comment 33•12 years ago
|
||
(In reply to Jonas Sicking (:sicking) from comment #32) > Almost all the time is spent in "syscall". Any ideas what that is? Could > that be the IO caused by IndexedDB? But if so I'm surprised that various > sqlite signatures aren't showing up. Note that all IndexedDB IO happens on > background threads in the parent process. syscall is just us waiting for events. This is only profile of the main thread.
Assignee | ||
Comment 34•12 years ago
|
||
(In reply to Jeff Muizelaar [:jrmuizel] from comment #33) > (In reply to Jonas Sicking (:sicking) from comment #32) > > Almost all the time is spent in "syscall". Any ideas what that is? Could > > that be the IO caused by IndexedDB? But if so I'm surprised that various > > sqlite signatures aren't showing up. Note that all IndexedDB IO happens on > > background threads in the parent process. > > syscall is just us waiting for events. This is only profile of the main > thread. In this case that was probably the time before I clicked the button. This profile has that cleaned up and is perhaps more clear: http://people.mozilla.com/~bgirard/cleopatra/?report=a54ae8205a8da05e0ff2b6dd9ed3cd3865de1fce Here's a bit of interpretation: At the beginning it looks like there's some runnable that's calling JSStructuredCloneReader::read() among other things. - 182ms in <Anonymous> - ContactDB.jsm:379 which calls makeExport() - 316ms in ContactService.jsm:117 - 150ms in sortfunction() - something that calls JSONParser:parse() - 297ms in ContactManager.js:345 - 1374ms in BrowserElementPromptService.jsm:30 which is showing the prompt for me.
Comment 35•12 years ago
|
||
Whats the status here?
Updated•12 years ago
|
Priority: -- → P2
Comment 36•12 years ago
|
||
Renom if you think we can't ship a v1 without this.
blocking-basecamp: + → ---
Comment 37•12 years ago
|
||
Per IRC conversations with a few other folks, I think the best course of action if there is disagreement on whether this blocks or not is to do the following: - Move the blocking-basecamp flag to ? for re-evaluation - Indicate a rationale for why you disagree
blocking-basecamp: --- → ?
Comment 38•12 years ago
|
||
We can't block on this until we get some actionable data ... but we'd really like to fix this! If we get some data, let's re-nom.
blocking-basecamp: ? → -
Reporter | ||
Comment 39•12 years ago
|
||
Requesting 500 contacts with a real OOP contacts app takes not 8-10 sec. This doesn't include the frontend rendering. I created a button in the gaia contacts tests that requests all contacts without the rendering part: https://github.com/gregorwagner/gaia/tree/perfTest There are several moving parts here: Bug 783057 increased the loading time for 500 contacts from around 2 sec to 4 sec for in-process. I will fix this in Bug 783645. Changing the nice value (http://mxr.mozilla.org/mozilla-central/source/b2g/app/b2g.js#509) to 0 decreases the loading time from 10 sec to around 8 sec. We would need a profile for the real OOP situation. Jeff, do you think you could help here?
Reporter | ||
Comment 40•12 years ago
|
||
The time until we see the 500 contacts with an OOP contacts app is around 16 sec. 9 sec until we get the contacts and 7 sec for the success CB.
blocking-basecamp: - → ?
Gregor, can you post a dump of a single contact now, with all the data and search strings, etc.? Just curious how big each contact is now.
Updated•12 years ago
|
blocking-basecamp: ? → +
Jeff, would you be able to bring this bug forward to the point of having actionable profile data?
Assignee: anygregor → jmuizelaar
Updated•12 years ago
|
Whiteboard: [LOE:M]
Morphing this bug to just cover profiling what's going on here since all the discussion and the assignment and time estimate is just for the profiling part.
Summary: Contacts API: improve performance → Contacts API: profile performance
Reporter | ||
Comment 44•12 years ago
|
||
(In reply to ben turner [:bent] from comment #41) > Gregor, can you post a dump of a single contact now, with all the data and > search strings, etc.? Just curious how big each contact is now. Basically it's just the contacts data + searchable fields that are stored lowercase + tel lookup fields: For example: contact: { "properties": { "name":["Testname1"], "honorificPrefix":null, "givenName":["Test1","Test2"], "additionalName":null, "familyName":["TestFamilyName","Wagner"], "honorificSuffix":null, "nickname":["nicktest"], "email":[{"type":["work"],"value":"x@y.com"}], "photo":null, "url":null, "category":null, "adr":[{ "type":"work", "streetAddress":"street 1", "locality":"locality 1", "region":"region 1", "postalCode":"postal code 1", "countryName":"country 1" }], "tel":[ { "type":["work"],"value":"123456","carrier":"testCarrier"},{"type":["home","fax"],"value":"+9-876-5432","carrier":null }], "org":null, "jobTitle":null, "bday":null, "note":null, "impp":null, "anniversary":null }, "search": { "name":["testname1"], "honorificPrefix":[], "givenName":["test1","test2"], "additionalName":[], "familyName":["testfamilyname","wagner"], "honorificSuffix":[],"nickname":["nicktest"], "email":["x@y.com"], "category":[], "tel":["123456","23456","3456","456","56","6","+9-876-5432","9-876-5432","-876-5432","876-5432","76-5432","6-5432","-5432","5432","432","32","2","98765432","8765432","765432","65432","5432","432","32","2"], "org":[], "jobTitle":[], "note":[], "impp":[] } }
Assignee | ||
Comment 45•12 years ago
|
||
I'm a bit confused about what else needs profiling here. The latest profiles I linked to are of the perf test. I believe those profiles are of the b2g process, do you also want a profile of plugin-container?
Comment 46•12 years ago
|
||
(In reply to Jeff Muizelaar [:jrmuizel] from comment #45) > I'm a bit confused about what else needs profiling here. The latest profiles > I linked to are of the perf test. I believe those profiles are of the b2g > process, do you also want a profile of plugin-container? AFAIK, the contacts app is now running OOP. We've also apparently gotten about 10x worse in terms of performance as a result of the OOP move :/
It is not, yet.
And the regression is 2-5x.
(In reply to Jeff Muizelaar [:jrmuizel] from comment #45) > I'm a bit confused about what else needs profiling here. The latest profiles > I linked to are of the perf test. I believe those profiles are of the b2g > process, do you also want a profile of plugin-container? Well, Gregor posted a link to a new test that will avoid the rendering overhead, so I think we need new profiles. One of each process would be awesome. Gregor, also, cjones noticed that we have a bunch of |debug(JSON.stringify(contact))| stuff. Even if debug() is disabled (e.g. defined to { }) then we'll still be creating these strings in release builds. We should remove this somehow (preprocessor?).
Comment 50•12 years ago
|
||
(In reply to ben turner [:bent] from comment #49) > Gregor, also, cjones noticed that we have a bunch of > |debug(JSON.stringify(contact))| stuff. Even if debug() is disabled (e.g. > defined to { }) then we'll still be creating these strings in release > builds. We should remove this somehow (preprocessor?). +1 to that. Or do what we do in the RIL: if (DEBUG) debug(...); Not pretty but effective.
Reporter | ||
Comment 51•12 years ago
|
||
(In reply to Philipp von Weitershausen [:philikon] from comment #50) > (In reply to ben turner [:bent] from comment #49) > > Gregor, also, cjones noticed that we have a bunch of > > |debug(JSON.stringify(contact))| stuff. Even if debug() is disabled (e.g. > > defined to { }) then we'll still be creating these strings in release > > builds. We should remove this somehow (preprocessor?). > > +1 to that. Or do what we do in the RIL: > > if (DEBUG) debug(...); > > Not pretty but effective. I will change this real quick in bug 784746.
Reporter | ||
Comment 52•12 years ago
|
||
With the patches from bug 784746 and bug 784099 I see now a reduction from 9 sec to 1.5 - 2 sec (500 contacts, OOP with UI tests-> contacts tests -> get all contacts).
Reporter | ||
Comment 53•12 years ago
|
||
We should re-evaluate with the new performance numbers.
blocking-basecamp: + → ?
The one remaining bit of data I want to see is in-process vs. OOP numbers with debugging removed.
Reporter | ||
Comment 55•12 years ago
|
||
(In reply to Chris Jones [:cjones] [:warhammer] from comment #54) > The one remaining bit of data I want to see is in-process vs. OOP numbers > with debugging removed. In process has the same performance as OOP. For 500 contacts around 1.5 sec. (It's hard to say exactly because I usually get +- 200 msec)
(In reply to Gregor Wagner [:gwagner] from comment #55) > In process has the same performance as OOP. For 500 contacts around 1.5 sec. > (It's hard to say exactly because I usually get +- 200 msec) /me dances a little!
Updated•12 years ago
|
blocking-basecamp: ? → -
Updated•11 years ago
|
Component: DOM: Device Interfaces → DOM: Contacts
Comment 57•6 years ago
|
||
DOM: Contacts isn't used anymore. Closing all remaining bugs.
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → WONTFIX
Updated•6 years ago
|
Product: Core → Core Graveyard
You need to log in
before you can comment on or make changes to this bug.
Description
•