Sync: Improve Bookmark association time when running with 10K+ bookmarks.
commit2af5d96b379df6df01133e985051311adc581935
authorstanisc <stanisc@chromium.org>
Tue, 30 Sep 2014 03:06:18 +0000 (29 20:06 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 30 Sep 2014 03:06:54 +0000 (30 03:06 +0000)
tree70e22527280990b0fa0161b581cf1ab3c45292e7
parent3a2e10b34a2990c931e0a2c2fb3c6ac935937dc2
Sync: Improve Bookmark association time when running with 10K+ bookmarks.

I profiled Bookmark Sync association code on a Windows workstation with about 16K folders and bookmarks. This was for the scenario when bookmarks had been already synced and and BookmarkModelAssociator::BuildAssociations needed to match sync data to the already existing bookmark model.

While it was fairly fast in absolute terms (less than 1 sec on my rather powerful workstation), I verified that 59% of samples for the UI thread were in BookmarkModelAssociator::BuildAssociations.

The top 3 functions called from BuildAssociations and their costs in terms of UI thread sample counts are:

browser_sync::BookmarkNodeFinder::FindBookmarkNode - 20.7%
browser_sync::BookmarkChangeProcessor::UpdateBookmarkWithSyncData - 14.6%
browser_sync::BookmarkNodeFinder::BookmarkNodeFinder - 13.9%

Altogether BookmarkNodeFinder was responsible for almost 35% of all UI thread samples.
Furthermore UTF16ToUTF8 function alone was responsible for 24% of UI thread samples.

The reason UTF16ToUTF8 is so expensive is because it is used in custom comparator used with multiset which is a part of BookmarkNodeFinder implementation.
Each bookmark node gets added and searched to BookmarkNodeFinder once.
Altogether that results in approx 2*2*(N*logN/2) calls of UTF16ToUTF8 (and
also N calls of UTF8ToUTF16). Each conversion involves an allocation.
On a mobile platform the relative cost of this should be even higher because
memory tends to be slower and CPU caches smaller.

The fix replaces multiset with a hash_multimap where the key is the converted
bookmark title. Therefore UTF16ToUTF8 ends up being called only once for each node and due to different lookup (by title vs. by node) UTF8ToUTF16 calls are eliminated.
Also hashing should work more efficiently for long bookmark/folder titles than the binary search.

Measurement showed that improved combined cost of BookmarkNodeFinder::BookmarkNodeFinder and BookmarkNodeFinder::FindBookmarkNode - close to 5x. And the overall cost of bookmark association - improved by 1.5-2x (when measured on my windows dev workstation).

There is also an opportunity to optimize UpdateBookmarkWithSyncData which blindly applies data even when it guaranteed to be exactly the same, but I didn't touch it in this change.

BUG=238621

Review URL: https://codereview.chromium.org/603153005

Cr-Commit-Position: refs/heads/master@{#297349}
chrome/browser/sync/glue/bookmark_model_associator.cc