Bug 177592 - [Decorators] [Contributions] ObjectContributionManager.getContributors(List) creates reams of garbage
Summary: [Decorators] [Contributions] ObjectContributionManager.getContributors(List) ...
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.3 M6   Edit
Assignee: Paul Webster CLA
QA Contact:
URL:
Whiteboard:
Keywords: performance
Depends on:
Blocks: 177392
  Show dependency tree
 
Reported: 2007-03-15 12:52 EDT by Nick Edgar CLA
Modified: 2007-03-21 14:41 EDT (History)
2 users (show)

See Also:


Attachments
Patch with changes to ObjectContributorManager (9.10 KB, patch)
2007-03-15 14:54 EDT, Nick Edgar CLA
no flags Details | Diff
Object Manager v02 (10.57 KB, patch)
2007-03-19 12:09 EDT, Paul Webster CLA
no flags Details | Diff
Patch to remove use of LinkedHashSet (3.86 KB, patch)
2007-03-19 13:55 EDT, Nick Edgar CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Edgar CLA 2007-03-15 12:52:47 EDT
3.3 M5

- expand each package in a moderately sized project
- to determine which decorators to apply, ObjectContributionManager.getContributors(List) is called repeatedly with a list of size 1, once for each element
- this call creates much garbage, e.g. 41.9M in a project containing ~600 items in my self-hosting environment (although some of this is in other overhead in LegacyResourceSupport, and in getResource() on JDT elements; see bug 177392 for more context)
- the great majority of this is produced in ObjectContributionManager.getCommonClasses(List, List), e.g. it's directly responsible for 29.5M in my setup

The general algorithm in getCommonClasses(List, List) is complex, however the case where n==1 (or, equivalently, when all objects are of the same class) can be easily optimized: the common class is the object's class, and the common adapters are the cached adapters for that class (available via the adapter manager).

I'll provide a patch optimizing this case, and a few other minor tweaks.
Comment 1 Nick Edgar CLA 2007-03-15 13:02:33 EDT
Also noticed that the dup removal code at the end of getContributors(List) is broken (in addition to taking O(N^2) time): it never checks uniqueContribs when iterating over contributors.

A better approach would be to use LinkedHashSet for the contributors var.  This acts like a set (so we don't end up with dups to begin with), but also preserves order, and is efficient.
Comment 2 Nick Edgar CLA 2007-03-15 13:13:20 EDT
Also: testList is not used in getResourceMappingClass, so it can be removed.
Comment 3 Nick Edgar CLA 2007-03-15 13:16:44 EDT
The various cache lookups (getResourceContributors, getAdaptableContributors, getObjectContributors) create a copy of the cached list, to protect against clients modifying the cached list.  Should wrap the cached list in Collections.unmodifiableList instead, to reduce garbage.
Comment 4 Nick Edgar CLA 2007-03-15 14:54:29 EDT
Created attachment 60998 [details]
Patch with changes to ObjectContributorManager

Michael, I'd appreciate if you could review this.  I'd be happy to sit down and go through it with you if you like.
Comment 5 Nick Edgar CLA 2007-03-15 15:02:30 EDT
With the changes in this patch, plus the patch to LegacyResourceSupport (see bug 177412), the garbage produced in ObjectContributionManager.getContributors(List) in my test scenario is reduced from 41.9M to 5.3M.  Bug 177412 saved about 5.4M, so this patch saves 41.9 - 5.3 - 5.4 = 31.2M, for a reduction in garbage of ~75%.

~2M of the remaining garbage is in JDT getResource() calls (i.e. not part of the getContributors algorithm).

Comment 6 Eric Moffatt CLA 2007-03-15 15:43:46 EDT
Paul, I'll give this to you regardless of the Component Area tags since it's in an area that I -know- you're looking at...
Comment 7 Paul Webster CLA 2007-03-16 07:52:28 EDT
We can look at this when you get in.
PW
Comment 8 Michael Valenta CLA 2007-03-16 14:59:36 EDT
I've loaded the patch and there are test case failures in PropertyPageEnablementTests. The ObjectContributionTests all passed though. So one option may be to push some of the changes down to ObjectActionContributionManager since the optimizations probably aren't as big a win for property pages.
Comment 9 Paul Webster CLA 2007-03-19 12:09:13 EDT
Created attachment 61301 [details]
Object Manager v02

I've updated getContributions(Object) to the same as getContributions(List) and I'm running tests.

Nick, could you please check the updated patch from your end?

PW
Comment 10 Nick Edgar CLA 2007-03-19 13:55:40 EDT
Created attachment 61316 [details]
Patch to remove use of LinkedHashSet

Paul's extra changes look good.  Here's a patch to remove the use of LinkedHashSet, which we can't use since it's not in Foundation.
Comment 11 Paul Webster CLA 2007-03-19 14:50:03 EDT
I've run the tests and submitted this to HEAD for the 18:00 EDT build

PW
Comment 12 Paul Webster CLA 2007-03-20 10:18:48 EDT
Fixed in I20070319-1800
PW
Comment 13 Paul Webster CLA 2007-03-20 20:32:22 EDT
Nick, could you please re-run your test on I20070320-1620?

Thanx,
PW
Comment 14 Nick Edgar CLA 2007-03-21 14:41:55 EDT
Verified in I20070821-0800.  The calls to ObjectContributionManager.getContributors(List) generate 3.26M, with only ~987M generated in getCommonClasses(List, List).

Thanks for reviewing/releasing the patch.