EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run...

37
Optimizing Performance how to make your Eclipse- based tools run faster Martin Lippert Principal Software Engineer - Pivotal [email protected] @martinlippert

description

Over the past year we worked a lot on the performance of the Spring-related tooling for Eclipse. In this session we present our lessons learned. We show how we identified Eclipse-specific performance bottlenecks, how we solved and/or worked around them, and demo the tools we used for this. We will walk through a number of real cases that we solved and discuss how we solved them. For example, we will discuss how we improved build times of Spring projects by a factor of 10, and reduced memory consumption at the same time. All of the presented cases are not specific to Spring tooling, so that the solutions are directly applicable to other Eclipse plugins. The areas that we will cover include using the JDT API, processing types and type hierarchies in source and class files, accessing resources and file content, scaling some algorithms, and more.

Transcript of EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run...

Page 1: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Optimizing Performance how to make your Eclipse-based tools run faster

Martin Lippert Principal Software Engineer - Pivotal

[email protected] @martinlippert

Page 2: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Every developer benefits from better performance

Page 3: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Find out where the problem is...

failblog.com

Page 4: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Measure !!!

Page 5: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

VisualVM !

Free Easy to use

comes as part of the JDK extremely useful to capture data remotely

Page 6: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

YourKit used for comprehensive analysis

various options and ways to track down issues $$$ !

!alternative: JProfiler

$$$

Page 7: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

the case

Page 8: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

trivial: expensive calls inside loops

Page 9: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

findFilesForLocationURI(..) is slow

step 1: fix this in the Eclipse platform

Page 10: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

findFilesForLocationURI(..) is slow

step 2: cache results if that makes sense

Page 11: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

findFilesForLocationURI(..) is slow

step 3: if you can‘t avoid massive use of this, optimize for the most likely case

Page 12: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Build workspace (16%)...

why is the build taking soooooo long... ???

Page 13: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Build workspace (16%)...

Page 14: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Build workspace (16%)...

what is exactly going on under the hood?

taken from a different case

Page 15: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Build workspace (16%)...

what is exactly going on under the hood?

• the Spring-specific builder: sloooooow...

taken from a different case

Page 16: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Build workspace (16%)...

what is exactly going on under the hood?

• the WTP JS builder: slooooow...

• the Maven project builder: slooooow...

• the Spring-specific builder: sloooooow...

taken from a different case

Page 17: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Build workspace (16%)...

what is exactly going on under the hood?

• the core implementation is ultra fast (compiling Java, for example, but also reconciling, invoking content assist, etc.)

• the WTP JS builder: slooooow...

• the Maven project builder: slooooow...

• the Spring-specific builder: sloooooow...

taken from a different case

Page 18: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

But wait a moment...

Page 19: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

what is this ?!?But wait a moment...

Page 20: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Action 1: Configure your Eclipse wisely

-Xmx768m !

!

!

-Xmx1024m

30min !

!

!

~7min

max heap size build workspace

Page 21: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Action 2: Reduce garbage and memory usage in general

• String.format creates a lot of garbage • called many many times • most of the time with exactly one argument

Page 22: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Action 2: Reduce garbage and memory usage in general

public Set<IBean> getBeans() { Set<IBean> allBeans = new LinkedHashSet<IBean>(beans.values()); for (IBeansImport beansImport : imports) { for (IBeansConfig bc : beansImport.getImportedBeansConfigs()) { allBeans.addAll(bc.getBeans()); } } return Collections.unmodifiableSet(allBeans); }

Page 23: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Action 2: Reduce garbage and memory usage in general

public Set<IBean> getBeans() { Set<IBean> allBeans = new LinkedHashSet<IBean>(beans.values()); for (IBeansImport beansImport : imports) { for (IBeansConfig bc : beansImport.getImportedBeansConfigs()) { allBeans.addAll(bc.getBeans()); } } return Collections.unmodifiableSet(allBeans); }

new set with copied content

recursive call

• imagine this is called with deep recursion • but since the method looks quite innocent, it is called

many times while doing the build

Page 24: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Now back to the details of this…

• the Spring-specific builder: sloooooow...

Page 25: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

O(n) matters for scalability

Page 26: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

class ResourceDeltaVisitor implements IResourceDeltaVisitor { ! public boolean visit(IResourceDelta aDelta) throws CoreException { IResource resource = aDelta.getResource(); if (resource instanceof IFile) { checkResource(resource); } return true; } }

watch out for visitors

Page 27: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

class ResourceDeltaVisitor implements IResourceDeltaVisitor { ! public boolean visit(IResourceDelta aDelta) throws CoreException { IResource resource = aDelta.getResource(); if (resource instanceof IFile) { checkResource(resource); } return true; } }

• this might be called many many times • take care to make this simple and fast • not allowed to iterate over collections

watch out for visitors

Page 28: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

class ResourceDeltaVisitor implements IResourceDeltaVisitor { ! public boolean visit(IResourceDelta aDelta) throws CoreException { IResource resource = aDelta.getResource(); if (resource instanceof IFile) { checkResource(resource); } return true; } }

• this might be called many many times • take care to make this simple and fast • not allowed to iterate over collections

• in our case: • takes a look at individual IResource objects • identify the defined types • iterate over all defined beans and check for type

dependency

watch out for visitors

Page 29: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

the case: type checks

Set<IType> typesToCheck = new HashSet<IType>(); ! IType[] types = cu.getAllTypes(); for (IType type : types) { IType[] subTypes = type.newTypeHierarchy(monitor).getAllSubtypes(type); if (subTypes != null && subTypes.length > 0) { typesToCheck.addAll(Arrays.asList(subTypes)); } } !!

loop over beans and check each bean type whether it is contained in typesToCheck

Page 30: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

the case: type checks

Set<IType> typesToCheck = new HashSet<IType>(); ! IType[] types = cu.getAllTypes(); for (IType type : types) { IType[] subTypes = type.newTypeHierarchy(monitor).getAllSubtypes(type); if (subTypes != null && subTypes.length > 0) { typesToCheck.addAll(Arrays.asList(subTypes)); } } !!

loop over beans and check each bean type whether it is contained in typesToCheck

• asking a type for its hierarchy is slow • cached, but only for a limited number of hierarchies • doing this for all resources of a build can take a very long time

Page 31: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

instead: we built our own type hierarchy engine

TypeHierarchyEngine it reads bytecode (only type information)

it walks up the super classes and interfaces it caches already loaded type information

Page 32: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

instead: we built our own type hierarchy engine

TypeHierarchyEngine it reads bytecode (only type information)

it walks up the super classes and interfaces it caches already loaded type information

Lessons Learned reading bytecode is super super fast

finding the bytecode on the classpath is super slow

Page 33: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

What is designed to be fast?

Reconciling Be extremely careful when implementing a

reconcile participant !

Content-Assist Has to be fast

Don‘t do anything if its not your job !

...

Page 34: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Startup time is important (even if you start Eclipse just once a day)

!

!

Don‘t start all your bundles and do stuff at startup

!

Do caching (Equinox Weaving, for example)

!

Uninstall bundles to get rid of things you don‘t need

Page 35: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Proposal mock-up – not an actual program

A different approach

from Chris Laffras talk on Eclipse performance

Page 36: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

1.Measure 2.Optimize !

3.Goto 1.

Page 37: EclipseCon-Europe 2013: Optimizing performance - how to make your Eclipse-based tools run fasterEce2013 optimizing performance

Martin Lippert Principal Software Engineer - Pivotal

[email protected] @martinlippert

Q&A !

and thank you for your attention