lishunli / projectlombok

Automatically exported from code.google.com/p/projectlombok
0 stars 0 forks source link

Profile eclipse 'clean' operations. #464

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Various reports on the newsgroup about lombok significantly slowing down (by a 
factor of 2 to 4) eclipse builds, particularly noticable in 'project clean' 
operations.

Because we don't have too many entrypoints (as per the agent 'hack') that could 
possibly eat up many CPU cycles, we can just instrument a few of those to 
measure time impact. That doesn't give us anything to compare it to (we'd have 
to manually hit some sort of reset button, then start a project clean, manually 
time the clean, and then hit a 'show total time taken by lombok' button to see 
what percentage was spent in lombok code), but it's a start. To go a little 
further we could just try to run a profiler on eclipse but I'm not sure that's 
going to produce useful results.

We could use agent hooks to hook into a 'project clean' command and do the 
timing stuff as mentioned above ourselves.

See: 
https://groups.google.com/forum/?hl=en-US&fromgroups=#!topic/project-lombok/hTZr
Qwnx46A

Original issue reported on code.google.com by reini...@gmail.com on 20 Mar 2013 at 2:10

GoogleCodeExporter commented 9 years ago
People experiencing performance problems compiling with javac (or maven, ant, 
etc.), can you try to delombok in one step and then compile the code without 
lombok on the classpath in a second step? What was the build time before first 
delombokking, and what was it after delombokking first.

Original comment by r.spilker on 21 Mar 2013 at 12:21

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I figured out, that building non-Lombok-projects also need longer for Building, 
if I activate Lombok in eclipse.ini.

Original comment by andi.mad...@gmail.com on 21 Mar 2013 at 12:32

GoogleCodeExporter commented 9 years ago
If I add these two lines to my eclipse.ini (using Rational Software Developer) 
ist needs 2-3 times more for building my project (regardless of using lombok or 
not!):

-javaagent:lombok-0.11.6.jar
-Xbootclasspath/a:lombok-0.11.6.jar

Original comment by andi.mad...@gmail.com on 21 Mar 2013 at 1:00

GoogleCodeExporter commented 9 years ago
Given that the slowdown occurs on all projects regardless of use of lombok, 
there are a few possible explanations that pop into my mind:

* Our run through the AST nodes to see if there are any lombok annotations 
present causes some slowdown, and as lombok has to do this _a lot_, it actually 
causes a lot of slowdown. I'm not quite sure how we can fix this.

* The fact that lombok makes the JVM that hosts eclipse run agents itself 
causes significant slowdown of that JVM. We can't fix this if this is the case.

* A specific lombok mechanism is causing a slowdown and is something we can 
remove altogether, or put in some filtering to only do that on files where 
it'll be necessary. This would of course be the good news, as we can fix this.

Original comment by reini...@gmail.com on 21 Mar 2013 at 4:09

GoogleCodeExporter commented 9 years ago
We only use @Getter/@Setter/@Data/@EqualsAndHashCode - but I think it is not 
possible to "turn off" other functions we do not need?

Original comment by andi.mad...@gmail.com on 22 Mar 2013 at 7:35

GoogleCodeExporter commented 9 years ago
Well, if the cause is related to the fact that we have to visit all ASTs 
produced by the java parser, turning off other features is not of any help.

You could use a different command line/shortcut to launch Eclipse for 
workspaces that don't have lombok right now. In the future, we might be able to 
detect if lombok is on the classpath or have an eclipse option to disable 
lombok for a project.

But I prefer to find the cause of performance problems and fix them, if 
possible :-)

Original comment by r.spilker on 22 Mar 2013 at 4:18

GoogleCodeExporter commented 9 years ago
I haven't thought through this but one idea that comes to mind is eclipse 
natures. What if you added a lombok nature to the project then you could use 
that to determine whether you should traverse the project looking for lombok 
annotations. This might require a full fledge lombok eclipse plugin and I don't 
know if that is something the team wants to explore but it might be worth some 
thought.

Original comment by xsegr...@gmail.com on 22 Mar 2013 at 6:30

GoogleCodeExporter commented 9 years ago
Roel and I spent the better part of 6 hours playing with JProfiler. Just 
cleaning lombok itself (which doesn't itself use any lombok) creates 500MB 
worth of HashSets. Now, it creates 0; we removed the need for them with some 
tactical refactoring. That'll help. There's also a huge CPU performance boost 
by switching the roles of updating Lombok AST mirrors: Instead of the traversal 
creating ArrayList clones so that any code can change the 'real' list, we now 
return the list itself and use a copy-on-write model where any changes to the 
list result in making a new one.

This may break a thing or two in third party plugins but the improvements are 
worth it hopefully.

Edge release here: http://projectlombok.org/download-edge.html

Original comment by reini...@gmail.com on 26 Mar 2013 at 1:50

GoogleCodeExporter commented 9 years ago
I'll test the new build these days - and I will try to delombok the code and 
build it without lombok to get a comparison, how many time is needed by lombok.

Thank you for your efforts!

Original comment by andi.mad...@gmail.com on 26 Mar 2013 at 9:54

GoogleCodeExporter commented 9 years ago
With the new Edge-Build I get the following error on all 
@EqualsAndHashCode-Annotations:

!ENTRY org.eclipse.jdt.core 4 0 2013-03-26 13:58:07.139
!MESSAGE Lombok annotation handler class 
lombok.eclipse.handlers.HandleEqualsAndHashCode failed
!STACK 0
java.lang.NoSuchMethodError: 
lombok/eclipse/EclipseNode.down()Ljava/util/Collection;
    at lombok.eclipse.handlers.HandleEqualsAndHashCode.generateMethods(Unknown Source)
    at lombok.eclipse.handlers.HandleEqualsAndHashCode.handle(Unknown Source)
    at lombok.eclipse.HandlerLibrary$AnnotationHandlerContainer.handle(Unknown Source)
    at lombok.eclipse.HandlerLibrary.handleAnnotation(Unknown Source)
    at lombok.eclipse.TransformEclipseAST$AnnotationVisitor.visitAnnotationOnType(Unknown Source)
    at lombok.eclipse.EclipseNode.traverse(Unknown Source)
    at lombok.eclipse.EclipseAST.traverseChildren(Unknown Source)
    at lombok.eclipse.EclipseNode.traverse(Unknown Source)
    at lombok.eclipse.EclipseAST.traverseChildren(Unknown Source)
    at lombok.eclipse.EclipseNode.traverse(Unknown Source)
    at lombok.eclipse.EclipseAST.traverse(Unknown Source)
    at lombok.eclipse.TransformEclipseAST.go(Unknown Source)
    at lombok.eclipse.TransformEclipseAST.transform(Unknown Source)
    at lombok.eclipse.TransformEclipseAST.transform_swapped(Unknown Source)
    at org.eclipse.jdt.internal.compiler.parser.Parser.endParse(Unknown Source)
    at org.eclipse.jdt.internal.core.util.CommentRecorderParser.endParse(Unknown Source)
    at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Unknown Source)
    at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Unknown Source)
    at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Unknown Source)
    at org.eclipse.jdt.internal.compiler.parser.Parser.dietParse(Unknown Source)
    at org.eclipse.jdt.internal.compiler.Compiler.accept(Unknown Source)
    at org.eclipse.jdt.core.dom.CompilationUnitResolver.accept(Unknown Source)
    at org.eclipse.jdt.core.dom.CompilationUnitResolver.accept(Unknown Source)
    at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.askForType(Unknown Source)
    at org.eclipse.jdt.internal.compiler.lookup.PackageBinding.getTypeOrPackage(Unknown Source)
    at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.findImport(Unknown Source)
    at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.findSingleImport(Unknown Source)
    at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.faultInImports(Unknown Source)
    at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.faultInTypes(Unknown Source)
    at org.eclipse.jdt.core.dom.CompilationUnitResolver.resolve(Unknown Source)
    at org.eclipse.jdt.core.dom.CompilationUnitResolver.resolve(Unknown Source)
    at org.eclipse.jdt.core.dom.ASTParser.internalCreateAST(Unknown Source)
    at org.eclipse.jdt.core.dom.ASTParser.createAST(Unknown Source)
    at org.eclipse.jpt.core.internal.utility.jdt.ASTTools.buildASTRoot(Unknown Source)
    at org.eclipse.jpt.core.internal.resource.java.source.SourceCompilationUnit.buildASTRoot(Unknown Source)
    at org.eclipse.jpt.core.internal.resource.java.source.SourceCompilationUnit.synchronizeWithJavaSource(Unknown Source)
    at org.eclipse.jpt.core.internal.AbstractJpaProject.processJavaCompilationUnitDelta(Unknown Source)
    at org.eclipse.jpt.core.internal.AbstractJpaProject.processJavaDelta(Unknown Source)
    at org.eclipse.jpt.core.internal.AbstractJpaProject.javaElementChanged(Unknown Source)
    at org.eclipse.jpt.core.GenericJpaProjectManager.javaElementChanged_(Unknown Source)
    at org.eclipse.jpt.core.GenericJpaProjectManager$6.execute_(Unknown Source)
    at org.eclipse.jpt.core.GenericJpaProjectManager$EventHandlerCommand.execute(Unknown Source)
    at org.eclipse.jpt.utility.internal.AsynchronousCommandExecutor$Consumer.execute(Unknown Source)
    at org.eclipse.jpt.utility.internal.ConsumerThreadCoordinator$RunnableConsumer.execute_(Unknown Source)
    at org.eclipse.jpt.utility.internal.ConsumerThreadCoordinator$RunnableConsumer.execute(Unknown Source)
    at org.eclipse.jpt.utility.internal.ConsumerThreadCoordinator$RunnableConsumer.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

Original comment by andi.mad...@gmail.com on 26 Mar 2013 at 1:00

GoogleCodeExporter commented 9 years ago
I've run a complete scan on the edge build, and this error is not possible; 
there are no references to the old version of the down() method anywhere in 
lombok-edge.jar. Are you using a custom lombok add-on plugin perhaps? Possibly 
there's an old lombok.jar around somewhere and somehow new and old lombok class 
files are getting mixed together?

Original comment by reini...@gmail.com on 26 Mar 2013 at 2:21

GoogleCodeExporter commented 9 years ago
Yes, we use a custom lombok-add-on - I'll have a look at it. As I can say so 
far (error  just comes with full clean) it is much faster. I hope I find the 
time to delombok the code and compare the build times with and without lombok. 
I'll keep you up to date!

Original comment by andi.mad...@gmail.com on 26 Mar 2013 at 4:40

GoogleCodeExporter commented 9 years ago
I did not have the time to delombok until now, but I figured out, that a 
collegue has no problems with the speed of Lombok in a smaller project. We use 
in our workspace up to 20 projects at once and it takes time - just 2-4 
projects are no problem.

Would it be possible to exclude projects/packages/classes at lombok? I only 
need it in 2 projects, the other ones could be excluded. Would it be possible 
to write excluded projects or packages in a file and give it to lombok to 
exclude these files from running through the AST nodes?

Original comment by andi.mad...@gmail.com on 27 Mar 2013 at 9:56

GoogleCodeExporter commented 9 years ago
I just delomboked the code and tried some things:
- Build time is now not much more with lombok than without with the new edge 
build.
- During the build without lombok I can work, save files - build process is 
done in background. If I do this with lombok, I always get a window which 
displays the progress bar and I have to wait for it. Every time saving I have 
to wait - but only at 92% (I think when lombok runs) - other time I can 
interrupt the build process without any troubles.
- I think we could speed up lombok, if we can exclude our EJB2-Projects. These 
projects do not use lombok, but the generate very much files.

Is there a possibility to get lombok working in background like the other build 
process? The "workflow" is much better without lombok, because with lombok I 
have to wait for any following action until the build process is finished.

Original comment by andi.mad...@gmail.com on 28 Mar 2013 at 10:19

GoogleCodeExporter commented 9 years ago
Not right now but we've got a base design where you can have settings per 
'level' (= a directory, which maps to both packages, source folders, projects, 
and entire workspaces so that part is nice), and one option will surely be: 
Just don't lombok at all.

As far as the thing where the background aspect halts, I have absolutely no 
clue why the heck that is happening, it's something we'll have to investigate.

Original comment by reini...@gmail.com on 26 Apr 2013 at 12:36

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
That level-implementation would be great.

As I said, it works better now, but excluding some projects/packages would be 
nice.

just don't lombok: I use it very much, I think I get an better overview over 
the beans without generating getters/setters...

Original comment by andi.mad...@gmail.com on 29 Apr 2013 at 8:41

GoogleCodeExporter commented 9 years ago
Hi guys, is there any update on this one? I project flag "Don't Lombok" would 
be highly appreciated. I have two projects in my workspace that use Lombok and 
the rest suffers from pretty severe performance hits. A quick sampling revealed 
EclipseNode.traverse() (11%) and EclipseAST.traverseChildren() (4.8%) to be of 
quite significant impact. I guess that's in line with what Reinier suspected.

Wouldn't a check, whether Lombok is in the classpath of a particular project be 
an elegant way of deciding whether to activate Lombok for a given project?

Original comment by oliver.gierke@me.com on 3 Jul 2013 at 2:38

GoogleCodeExporter commented 9 years ago
We have some proof-of-concept code figuring out the "current classpath", but 
it's not ready to put into production. And that's only the first step. But on 
the other hand, I think we should be able to boost the general performance by 
spending some more time with a profiler.

Original comment by r.spilker on 3 Jul 2013 at 9:43

GoogleCodeExporter commented 9 years ago
Couldn't you simply scan the whole file for the String "lombok" before you 
start? If it's not there, then there can be no Lombok annotation (neither 
imported not FQN) and you're done. Or hook into the Scanner?

Original comment by Maaarti...@gmail.com on 30 May 2014 at 6:51