Eclipse Java Compiler for on-fly java compilation is slow [message #1075925] |
Tue, 30 July 2013 10:41  |
Eclipse User |
|
|
|
Hi all,
we are using Eclipse Java Compiler (ejc 3.5.1) for on-fly compilation of java files. We compile single file using our two jars in additional classpath. Here is an example of our call:
JavaCompiler compiler = new EclipseCompiler();
ClassFileManager fileManager = new ClassFileManager(null, null);
LOG.info("Classpath: " + classPath);
fileManager.handleOption("-classpath", additionalLibs.iterator());
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
List<? extends JavaFileObject> files = Collections.singletonList(new CharSequenceJavaFileObject(className, src));
boolean result = compiler.getTask(new OutputStreamWriter(new NullOutputStream()), fileManager, diagnostics, optionList, null, files).call();
if (result) {
return fileManager.getJavaClassObject().getBytes();
} else {
...
}
We compile each file in separate task because we have a custom classloader that tries to find class and if it is not available, it runs compilation using ecj (code is fetched from storage) and builds class based of received bytecode.
So during the first execution we need to compile about hundred of classes and it looks slow. Compilation of a single file takes 0.5-1 sec. I run it with profiler: i.imgur.com/UHySdLo.png
Here is a call stack to the longest isPackage function:
at org.eclipse.jdt.internal.compiler.batch.ClasspathJar.isPackage(ClasspathJar.java:147)
at org.eclipse.jdt.internal.compiler.batch.ClasspathJar.findClass(ClasspathJar.java:93)
at org.eclipse.jdt.internal.compiler.batch.FileSystem.findClass(FileSystem.java:242)
at org.eclipse.jdt.internal.compiler.batch.FileSystem.findType(FileSystem.java:334)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.createPackage(LookupEnvironment.java:700)
at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.buildTypeBindings(CompilationUnitScope.java:89)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.buildTypeBindings(LookupEnvironment.java:152)
at org.eclipse.jdt.internal.compiler.Compiler.internalBeginToCompile(Compiler.java:717)
at org.eclipse.jdt.internal.compiler.Compiler.beginToCompile(Compiler.java:377)
at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:426)
at org.eclipse.jdt.internal.compiler.batch.Main.performCompilation(Main.java:3687)
at org.eclipse.jdt.internal.compiler.tool.EclipseCompilerImpl.call(EclipseCompilerImpl.java:69)
at org.eclipse.jdt.internal.compiler.tool.EclipseCompiler$1.call(EclipseCompiler.java:181)
Looks like it this function is small, but it is called 9.5M times for 250 compilations of single file, having two our jars in classpath. Is it possible somehow to improve performance of this compilation, or the only solution is to compile all files in one run?
Thanks.
|
|
|
Re: Eclipse Java Compiler for on-fly java compilation is slow [message #1079611 is a reply to message #1075925] |
Sun, 04 August 2013 21:48  |
Eclipse User |
|
|
|
This sounds like an unusual usage scenario for ecj.
When you freshly invoke ecj for each individual file it has no memory of what happened before, so it *must* access resources on the classpath to do proper compilation. Naturally, everything that boils down to file system access is a candidate for slowing down. I would guess that the biggest penalty is reading from rt.jar.
Maybe you get a chance to improve by tweaking the classpath so that it doesn't contain all libraries of the JRE? If most of the classes would use only a small fraction of the JRE, you could provide this subset on your classpath, and when compilation fails in this setting for a few demanding classes you could still fall back to compiling against the full JRE - Just a wild idea.
Otherwise, if you have the option to compile many files in bulk, that's certainly the most promising road.
Stephan
|
|
|
Powered by
FUDForum. Page generated in 0.03691 seconds