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

Martin Lippert	

Principal Software Engineer - Pivotal	

mlippert@gopivotal.com	

@martinlippert

Optimizing	

Performance	

how to make your Eclipsebased tools run faster
Every developer benefits
from better performance
Find out where the problem is...

failblog.com
Measure !!!
VisualVM
!

Free	

Easy to use	

comes as part of the JDK	

extremely useful to capture data remotely
YourKit

used for comprehensive analysis	

various options and ways to track down issues	

$$$	

!
!

alternative:	


JProfiler
$$$
the case
trivial: expensive calls inside loops
findFilesForLocationURI(..) is slow

step 1: fix this in the Eclipse platform
findFilesForLocationURI(..) is slow

step 2: cache results if that makes sense
findFilesForLocationURI(..) is slow
step 3: if you can‘t avoid massive use of this,

optimize for the most likely case
Build workspace (16%)...

why is the build taking	

soooooo long... ???
Build workspace (16%)...
Build workspace (16%)...
taken from a different case

what is exactly going on under the hood?
Build workspace (16%)...
taken from a different case

what is exactly going on under the hood?
•

the Spring-specific builder: sloooooow...
Build workspace (16%)...
taken from a different case

what is exactly going on under the hood?
•

•

the Spring-specific builder: sloooooow...

the Maven project builder: slooooow...

•

the WTP JS builder: slooooow...
Build workspace (16%)...
taken from a different case

what is exactly going on under the hood?
•

•

the Spring-specific builder: sloooooow...

the Maven project builder: slooooow...

•

the WTP JS builder: slooooow...

•

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

what is this ?!?
Action 1: Configure your Eclipse wisely

max heap size

build workspace

-Xmx768m

30min

!

!

!

!

!

!

-Xmx1024m

~7min
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
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);
}
Action 2: Reduce garbage
and memory usage in general
new set with copied content











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);
}
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
Now back to the details of this…

•

the Spring-specific builder: sloooooow...
O(n)
matters for scalability
watch out for visitors


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


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


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
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
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
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
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
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	

!

...
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
A different approach
Proposal mock-up – not an actual program

from Chris Laffras talk on Eclipse performance
1.Measure
2.Optimize
!

3.Goto 1.
Q&A
!
and thank you for your attention

Martin Lippert	

Principal Software Engineer - Pivotal	

mlippert@gopivotal.com	

@martinlippert
1 of 37

More Related Content

What's hot(10)

Viewers also liked(10)

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

Why Spring <3 KotlinWhy Spring <3 Kotlin
Why Spring <3 KotlinVMware Tanzu
1.4K views75 slides
Twig tips and tricksTwig tips and tricks
Twig tips and tricksJavier Eguiluz
199.3K views185 slides

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

Developing Useful APIsDeveloping Useful APIs
Developing Useful APIs
Dmitry Buzdin1K views
Why Spring <3 KotlinWhy Spring <3 Kotlin
Why Spring <3 Kotlin
VMware Tanzu1.4K views
Refactoring In Tdd The Missing PartRefactoring In Tdd The Missing Part
Refactoring In Tdd The Missing Part
Gabriele Lana7.9K views
Twig tips and tricksTwig tips and tricks
Twig tips and tricks
Javier Eguiluz199.3K views
Test-driven Development for TYPO3Test-driven Development for TYPO3
Test-driven Development for TYPO3
oliverklee7.6K views
Chapter 4Chapter 4
Chapter 4
EasyStudy315 views
KotlinKotlin
Kotlin
Rory Preddy1.2K views
Lists and scrollbarsLists and scrollbars
Lists and scrollbars
myrajendra997 views
AttributeAttribute
Attribute
Luke Smith1.4K views
Firebase & SwiftUI WorkshopFirebase & SwiftUI Workshop
Firebase & SwiftUI Workshop
Peter Friese158 views
Cross platform mobile development Cross platform mobile development
Cross platform mobile development
Alberto De Bortoli527 views
Java 8: the good parts!Java 8: the good parts!
Java 8: the good parts!
Andrzej Grzesik10.7K views
JavaOne 2013: Java 8 - The Good PartsJavaOne 2013: Java 8 - The Good Parts
JavaOne 2013: Java 8 - The Good Parts
Konrad Malawski40.3K views

Recently uploaded(20)

The Research Portal of Catalonia: Growing more (information) & more (services)The Research Portal of Catalonia: Growing more (information) & more (services)
The Research Portal of Catalonia: Growing more (information) & more (services)
CSUC - Consorci de Serveis Universitaris de Catalunya51 views
Liqid: Composable CXL PreviewLiqid: Composable CXL Preview
Liqid: Composable CXL Preview
CXL Forum118 views
CXL at OCPCXL at OCP
CXL at OCP
CXL Forum183 views

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

  • 1. Martin Lippert Principal Software Engineer - Pivotal mlippert@gopivotal.com @martinlippert Optimizing Performance how to make your Eclipsebased tools run faster
  • 2. Every developer benefits from better performance
  • 3. Find out where the problem is... failblog.com
  • 5. VisualVM ! Free Easy to use comes as part of the JDK extremely useful to capture data remotely
  • 6. YourKit used for comprehensive analysis various options and ways to track down issues $$$ ! ! alternative: JProfiler $$$
  • 9. findFilesForLocationURI(..) is slow step 1: fix this in the Eclipse platform
  • 10. findFilesForLocationURI(..) is slow step 2: cache results if that makes sense
  • 11. findFilesForLocationURI(..) is slow step 3: if you can‘t avoid massive use of this,
 optimize for the most likely case
  • 12. Build workspace (16%)... why is the build taking soooooo long... ???
  • 14. Build workspace (16%)... taken from a different case what is exactly going on under the hood?
  • 15. Build workspace (16%)... taken from a different case what is exactly going on under the hood? • the Spring-specific builder: sloooooow...
  • 16. Build workspace (16%)... taken from a different case what is exactly going on under the hood? • • the Spring-specific builder: sloooooow... the Maven project builder: slooooow... • the WTP JS builder: slooooow...
  • 17. Build workspace (16%)... taken from a different case what is exactly going on under the hood? • • the Spring-specific builder: sloooooow... the Maven project builder: slooooow... • the WTP JS builder: slooooow... • the core implementation is ultra fast (compiling Java, for example, but also reconciling, invoking content assist, etc.)
  • 18. But wait a moment...
  • 19. But wait a moment... what is this ?!?
  • 20. Action 1: Configure your Eclipse wisely max heap size build workspace -Xmx768m 30min ! ! ! ! ! ! -Xmx1024m ~7min
  • 21. 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
  • 22. 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); }
  • 23. Action 2: Reduce garbage and memory usage in general new set with copied content 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); } 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
  • 24. Now back to the details of this… • the Spring-specific builder: sloooooow...
  • 26. watch out for visitors class ResourceDeltaVisitor implements IResourceDeltaVisitor { } ! public boolean visit(IResourceDelta aDelta) throws CoreException { IResource resource = aDelta.getResource(); if (resource instanceof IFile) { checkResource(resource); } return true; }
  • 27. watch out for visitors 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
  • 28. watch out for visitors 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
  • 29. 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
  • 30. 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
  • 31. 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
  • 32. 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
  • 33. 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 ! ...
  • 34. 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
  • 35. A different approach Proposal mock-up – not an actual program from Chris Laffras talk on Eclipse performance
  • 37. Q&A ! and thank you for your attention Martin Lippert Principal Software Engineer - Pivotal mlippert@gopivotal.com @martinlippert