Community
Participate
Working Groups
I20080520-2000 In a development workspace with JDT, Debug and PDE plug-ins from CVS, open DebugPlugin.java, type a space (that does not change the class file), and save the file. The Java builder takes less than 0.5 seconds, but the API Tools builder needs about 30 seconds to finish. This makes it a pain to work with compilation units that have a lot of incoming dependencies, and there's no way for me to improve the situation (except for disabling auto build).
Apart from the unnecessary recomputation in cases where the class file did not change, a lot of time (>50%) is spent in HashMap#get(Object) comparing MethodDescriptorImpl#equals(Object).
Markus, is this consistent, or was this a first time hit?
> Markus, is this consistent, or was this a first time hit? This is what I can consistently reproduce when I add another space and save the editor again. The first time hit was probably even worse. What I have to admit though, is that I'm running a bit low on memory (400MB is not enough any more...), so garbage collections could have been a factor. I tried to restart and measure again, but Eclipse started an unmotivated full build. I'll report times as soon as the build is done.
I see somewhere between 10-15 seconds with these projects in my workspace: org.eclipse.jdt.doc.user org.eclipse.pde.doc.user org.eclipse.releng org.eclipse.test.performance.win32 org.eclipse.ant.core org.eclipse.ant.tests.core org.eclipse.ant.tests.ui org.eclipse.ant.ui org.eclipse.core.variables org.eclipse.debug.core org.eclipse.debug.examples.core org.eclipse.debug.examples.ui org.eclipse.debug.ui org.eclipse.jdt.core org.eclipse.jdt.core.tests.builder org.eclipse.jdt.core.tests.compiler org.eclipse.jdt.debug org.eclipse.jdt.debug.tests org.eclipse.jdt.debug.ui org.eclipse.jdt.launching org.eclipse.jdt.ui org.eclipse.jface.text org.eclipse.pde.api.tools org.eclipse.pde.api.tools.tests org.eclipse.pde.api.tools.ui org.eclipse.pde.core org.eclipse.pde.ui org.eclipse.pde.ui.tests org.eclipse.test.performance org.eclipse.ui.console org.eclipse.ui.externaltools org.objectweb.asm
(In reply to comment #4) > I see somewhere between 10-15 seconds with these projects in my workspace: I agree there is room for improvement :-)
OK, after a restart, the initial time came down to about 20s. After all caches have been populated, the API Tools builder still took 10 seconds for a no-op change on a single file. This is with a 3.3.2 baseline, of course.
When a file changes in any way (we consider all changes since we also care about javadoc changes), API tooling: * analyzes the changed file for: - unsupported tags - illegal API use - compatibility problems - @since tag problems * analyzes and all of its dependents for - illegal API use However, it seems that we should only analyze dependents of types who's API description has changed. If the API description of a type has not changed, then dependents use of API has not changed.
See the fix for bug 233731. The simple fix greatly improves this things. As well, there is room for more improvement by reducing analysis of dependents (but it requires more code).
Created attachment 101805 [details] patch This patch only re-analyzes dependents of types who's API description has changed. It further reduces memory consumption by not retaining member types in API descriptions that have no explicit API Javadoc tags. This also reduces the size of our persisted API descriptions. After a clean & full build with my 33 project workspace: Allocated HEAP: 362 Retained HEAP: 141 This is a further 8MB reduction from the patch in bug 233731. The time for a no-op build is still around 3 seconds - so the extra logic for "has API description changed" does not seem to effect things as much as memory consumption, but it still feels faster.
Consider for RC3
The part of this fix that vastly improves performance is included in bug 233731. Moving this bug to 3.4.1 since it is a bigger change that does not have as much impact.
Markus, can you try API tooling in the latest build and let us know if the performance is now acceptable (I20080527-2000).
Thanks for all the improvements! I think it's OK now for 3.4. In I20080527-2000, the API Tools builder used about 20s for the first run, and about 5s when all caches were pre-filled. In a CPU trace, I didn't see obvious hot spots any more (especially HashMap#get(Object) is gone). o.e.pde.api.tools still keeps a lot of heap (currently 50MB in my workspace), but bug 233731 was definitely an improvement.
Thanks Markus.
Moving to 3.5
R3.4: I changed a value in the manifest of ltk.core which resulted in several minutes API builder work (comparing base line).
I still often have to wait several minutes after doing minor changes. Could you please schedule some cycles for this early in 3.5?
At least major. Had to change jface.text manifest to 3.5.0 (because I got an API tooling error after adding a new interface) and then I was blocked because it took > 10 minutes to build.
Ping. This is important and should be investigated before M7. The API builder is still a major pain point for day-to-day development, since it often increases build time by a magnitude.
(In reply to comment #19) > Ping. This is important and should be investigated before M7. The API builder > is still a major pain point for day-to-day development, since it often > increases build time by a magnitude. Do you have a specific example again - it has been helpful in the past. Is this a start-up hit, or an every-time hit?
> Do you have a specific example again - it has been helpful in the past. Is this > a start-up hit, or an every-time hit? I mostly see this when I go over incoming change sets in the CVS view. I look at some of the changes and update in batches when I'm done with a few change set. In this case, most of they affected files are not yet in the disk cache. An example is comment 18. I added a newline at the end of /org.eclipse.jface.text/META-INF/MANIFEST.MF and saved the file. After this, the auto-build took about 2 minutes, and the progress view showed messages like: - Checking API used by ... - Scanning <a-source-folder-path' for unsupported API Javadoc tags
Here's the ultimate test case: - I have SWT from HEAD (linked .classpath to .classpath_win32) - I replaced the current version of class Display (1.313) with 1.312 -> the only difference is that 1.312 removes 2 method calls -> Java builder is done within seconds -> API Tools builder thrashes my disk for 2 minutes and 22 seconds
May last comment from half a year ago was: "At least major.". The situation hasn't improved for me. Java builder finishes in seconds and then sometimes disk and CPU gets hogged for minutes. Can this get higher priority please? Thanks.
Assigning to Olivier for investigation.
(In reply to comment #22) > Here's the ultimate test case: > - I have SWT from HEAD (linked .classpath to .classpath_win32) > - I replaced the current version of class Display (1.313) with 1.312 > -> the only difference is that 1.312 removes 2 method calls > -> Java builder is done within seconds > -> API Tools builder thrashes my disk for 2 minutes and 22 seconds What other projects do you have as source projects in your workspace ?
Created attachment 126467 [details] projects in my workspace (In reply to comment #25) > What other projects do you have as source projects in your workspace ? Most of the SDK (except for equinox, p2, update; see the attached list), and a few small private projects. The main issue here seems to be that API tools have no or too weak dependency information and often compile everything even if the concrete changes cannot affect dependencies (e.g if only a method body has been changed, but not the interface). This probably also hampers the OS's disk cache.
I will takes this to look at how and why we are collecting / scanning the types that we do. I would be willing to bet we are scanning far too many types by each part of the builder. For example when we collect the dependent types of a type the Java build reports has changed, we only need to scan those types in some of our scans, but right now we scan them all in all of our scans. So for scans like binary compatibility and internal leaks we do not care about the non-structurally changed types, only the ones the Java builder reported originally. Investigating.
Created attachment 126895 [details] first patch Here is a patch for cutting down on the types that are analyzed during an incremental build. Specifically the patch properly separates the types that have actually been changed from those that we have identified an dependent (on the changed types). This patch also fixes the inconsistent test result mentioned in bug 264369 and there are also a couple of looping performance changes (and a bit of code clean up). All tests pass in Linux and Windows....have yet to test it on the Mac
continued work of pruning / validating types to check has led to a much larger solution than expected, moving to M7 to have more time to properly test.
Created attachment 127856 [details] work in progress This patch is a work in progress that separates our incremental building from our builder (much like the IncrementalImageBuilder and the JavaBuilder). This patch also changes the way to pre-deterine if we need a full build when an incremental one has been requested. The next step is to remove our heavy delta listener code and opt for the IResourceProxyVisitor code as well as clean up the reduced type scanning.
committed DependentUsageTests which are required to ensure the new incremental builder code works properly
Created attachment 130342 [details] updated fix This update: 1. separates out the incremental builder from our base builder 2. improves the way we determine if a full build should occur when an incremental one has been requested 3. fixes a bug where successive tag changes were not causing the correct non-structural dependents to be built 4. reduces the amount of calls to clean up markers Still to be done: 1. we spend a lot of cycles trying to determine what markers should be cleaned, this process needs to be simplified - since we create them we should immediately know how to remove them 2. we need a better story for collecting / processing primary types and their member types. Currently we do this by collecting ITypes from the Java model and asking about existence - which can be expensive - we should examine augmenting our API type containers to return parent and child types when needed 3. we should look at leveraging IResourceProxyListener like the Java builder does to avoid visiting as many elements as possible
> 2. we need a better story for collecting / processing primary types and their > member types. Currently we do this by collecting ITypes from the Java model and > asking about existence - which can be expensive - we should examine augmenting > our API type containers to return parent and child types when needed I didn't look at the code, but FYI: The SearchEngine#searchAllTypeNames(..) is usually the quickest way to find existing type declarations, see e.g. how the 'Open Type' dialog uses it in FilteredTypesSelectionDialog#fillContentProvider(..).
(In reply to comment #33) > I didn't look at the code, but FYI: The SearchEngine#searchAllTypeNames(..) is > usually the quickest way to find existing type declarations, see e.g. how the > 'Open Type' dialog uses it in > FilteredTypesSelectionDialog#fillContentProvider(..). > Thanks for the pointers Markus, I will look into that.
committed first round of updates to HEAD
Created attachment 130743 [details] next update This fix includes improved type collecting and marking updating as well as a bit less memory usage by storing less delta infos
committed patch to HEAD
Created attachment 130860 [details] update This patch builds on the previous one with less memory usage for processing removed types and better marker management.
applied patch to HEAD
Created attachment 131061 [details] update This patch removes some (more) now dead code to further enhance marker cleanup, it also refactors a bit of the buildstate code
moving to 3.6. The last required major fix for this bug (bug 273295) is much too large to go in to RC1 so it needs to be deferred.
Created attachment 153351 [details] patch This is the latest updated patch to include the applied PDE fix for the DependencyManager. This work falls under this bug, more so than the root bug 280464.
(In reply to comment #43) > This work falls under this bug, more so than the root bug 280464. better still this should be in its own bug to better track what has been fixed, etc. see bug 296487.
Created attachment 155857 [details] screen shot of performance results from I20100107-1410 relative to R-3.5-200906111540
Marking fixed. Incremental build is about 50% faster since 3.5.