Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 386856

Summary: Performance - improve performance of BinaryPackageFragment#buildClassFiles() by approximately 60%
Product: [WebTools] Dali JPA Tools Reporter: Karen Butzke <karenfbutzke>
Component: JPAAssignee: Karen Butzke <karenfbutzke>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: brian.vosburgh, ccc, karenfbutzke, mcraquel, melickm, neil.hauge, tjbishop
Version: 3.0.2   
Target Milestone: 3.0.3   
Hardware: PC   
OS: Windows 7   
Whiteboard:
Bug Depends on: 379853    
Bug Blocks:    

Description Karen Butzke CLA 2012-08-08 11:46:49 EDT
+++ This bug was initially created as a clone of Bug #379853 +++

Build Identifier: 

I've been looking into a problem we have in our WTP adopter product where the first expansion of a project can hang the UI thread for a very long period of time.  When that project has the JPA facet a very large percentage of the time is spent doing the build of the JPA model.  While the changes done for bug 336403 (and hopefully bug 379755) will help improve the usability of the product while this long action occurs... it still is a problem that this functionality does not scale well when dealing with projects that contain a lot of binary JAR content.

For example, I have a web project (with the JPA facet) and it takes approximately 3.5 minutes to build the JPA model.  This is a rather long time for a user to have to wait for the UI to respond.

I was able to see this problem by modifying the method org.eclipse.jpt.core.internal.buildJpaFile(JpaProject, IFile, IContentType) to add some trace statements which show hold long it takes to build the resource model.  For example:

	long start = System.currentTimeMillis();
	JpaResourceModel resourceModel = this.buildResourceModel(jpaProject, file, contentType);
	long finish = System.currentTimeMillis();
	long diff = finish - start;
	System.out.println("Done building resource model for '" + file + "' in " + diff + "ms.");

For some of the JAR files that are contained within my project I see that it can take many seconds. Depending on the JAR file it various from 1s to 19s.  Here is the worst offender for me:

Done building resource model for 'L/MyProject/WebContent/WEB-INF/lib/xalan-2.6.0.jar' in 19078ms.

Overall, the entire build for my project took a time of 211081ms (3.5min).

I continued investigating and found that a large amount of this time is spent in org.eclipse.jpt.core.internal.resource.java.binary.BinaryPackageFragment#buildClassFiles() where it is trying to build a cache of, what looks to be, annotated binary classes:

	IType jdtType = jdtClassFile.getType();
	if (BinaryPersistentType.typeIsPersistable(jdtType)) {
		JavaResourceClassFile classFile = new BinaryClassFile(this, jdtClassFile, jdtType);
		if (classFile.getPersistentType().isAnnotated()) {  // we only hold annotated types
			result.add(classFile);
		}
	}

I was able to modify this method to reduce the time this method takes by approximately 60% (but this various depending on the JAR file being processed) by changing the code to do the following:

	IType jdtType = jdtClassFile.getType();
	if (BinaryPersistentType.typeIsPersistable(jdtType)) {
		boolean hasAnnotations = false;
		try {
			hasAnnotations = (jdtType.getAnnotations().length > 0);
		}
		catch(JavaModelException javaModelEx) {
			JptCorePlugin.log(javaModelEx.getStatus());
		}
		if (hasAnnotations) { // we only hold annotated types
			JavaResourceClassFile classFile = new BinaryClassFile(this, jdtClassFile, jdtType);
			result.add(classFile);
		}
	}

which I believe is functionally equivalent to the current code (but please correct me if I am wrong).  The xalan JAR previously mentioned now takes the following time:

Done building resource model for 'L/MyProject/WebContent/WEB-INF/lib/xalan-2.6.0.jar' in 3656ms.

which is a (19078 - 3656) = 15422 ms (or 80%) savings for this single JAR file.

Overall, the new build took a total time of 79391ms to build.

which is a 211081 - 79391 = 131690 ms (or 62%) savings.

The adopter product I work with us currently using the Dali 2.3 code base and the code I modified was done against the org.eclipse.jpt.core bundle from the R2_3_maintenance branch in CVS.  I will attach a patch for this change.

Do you consider this a safe patch to include in the R2_3_maintenance CVS branch and all the other streams after this release?  If so, would it be possible to incorporate it?  Thank you!

Reproducible: Always
Comment 1 Karen Butzke CLA 2012-08-08 12:27:40 EDT
fixed this in R3_0_maintenance branch with commit -
http://git.eclipse.org/c/dali/webtools.dali.git/commit/?id=8e72879c563353eefb7e3ca37ddc56938869536b