(Français) Choisir Scala en entreprise, est-ce bien raisonnable ?

Sorry, this entry is only available in Français.

Optimizing Eclipse performances

Especially for Scala projects

We love Eclipse. I mean, it’s clearly the best IDE around[1]. And we love to hate it. It is bloated. To make it useful, you have to cherry pick among hundreds of modules, and figure out how to make them work together. And it’s slow. OK, at the beginning, everything is running smoothly, but time passing, habits coming, things start to spoil, and at the end, it is sooooo slow. It reminds us of some youthful errors, the worst time of Windows, when performance decreased slowly over time. And there are really few projects where the number of lines of code decrease… Oh, if the code is only Java, you may not notice at once, but one morning you fire Eclipse, go to take a coffee, and return with that little “refreshing workspace” text still staring at you.

But the worst happens when you have to use plugins for some other technologies, like Maven[2], or another language with a not-quite-as-optimized-plugin-as-the-Java-one, or one relying heavily on weaving and indexes. Or a mix of all these things. In such an unlucky scenario, you may find yourself spending most of your time waiting for a pop-up to pop, a cursor to reach the point you just clicked on, and so on. And that is bad.

Time is money, flow is priceless

That is bad, not so much for all the little milliseconds wasted (even if at the end of the day, the sum might not be discarded so easily), but because all these little interruptions break your development flow, and that costs a price you really don’t want to pay[3].

OK, it also makes you want to throw your computer out the window, which would be bad for the environment. And your computer.

Scala, the worst of both worlds

All these little annoyances seems to be exacerbated with Scala and its Eclipse plugin: each Scala class may generate tens of compiled classes, the plugin heavily relies on JDT weaving and caches a lot of information in indexes. It also keeps track of what should be recompiled and when, with all that information also in indexes – and all these indexes, and your source files, seem to spend most of their time synchronizing to disk. Last thing – above everything else, the Scala compiler is in no way as fast as the Java one, perhaps even orders of magnitude slower[4].

So, we want to improve compilation speed and responsiveness, even if it means using more memory and CPU – both are affordable nowadays, and time still seems to be the missing resource.

So, stop babbling, what next ?

The rest of this article browses general recommendations about Eclipse, that everybody should spend some time on. These recommendations are basic stuff you just have to do it: no risk, little time, and perhaps good gains.

A second article will follow this first one (Edit: it’s here). It deals with setting Eclipse workspace in RAM thanks to tmpfs. It is much more involved, and the procedure will only be given for a Linux box. The good news is that gains may be exceptional – at least, they were for me.

All this advice is based on my personal experience, and is relevant for the Sun virtual machine, on a Linux desktop. So, your mileage may vary with other JVM, OS, development habits, plugins. Of course, we would LOVE to see in comments what your tips and tricks to make Eclipse a blazing lighting horse of war are – well, or at least something better than the stubborn donkey it seems to be sometimes.

Buy some RAM…

…or perhaps a fresh new computer. Seriously, how much does 2 GB of RAM cost, or even 8 GB, compared to one development day? Having decent hardware is perhaps the simplest and most effective way to get Eclipse boosted – and at the same time, you’ll also get a faster browser, faster image editing, faster OS… A whole faster desktop.

In that regard, choosing to buy an SSD disk seems to be a kind of blessing for Eclipse[5].

But if you can’t afford to buy one, and have some RAM to spare, you’ll like knowing how to put all of your workspace in RAM and feel what speed means.

Use the latest Eclipse on the latest JVM

The second obvious advice is to use the latest stable version of your software, especially the latest version of your JVM. Its performance is becoming better and better with each release, and it is even more noticeable if you are dealing with technologies other than plain Java. Between JVM 1.6u15 and 1.6u18, there was a noticeable gain with Scala – and if it is humanly noticeable, just think about how much improvement it means.

So, if your Eclipse is not running on JVM 1.6u20 (current version at time of writing), stop everything else, go download it[6] and use it to run Eclipse. As far as I know (what means nothing about Java for mobiles), there is no obvious excuse for not doing so, as Eclipse allows you to configure other JVM to compile and run your programs. You can check the JVM used by Eclipse in “Help -> About Eclipse -> Installation Details”, “Configuration” tab, and look for the -vm argument.

Throw out .metadata

Sometime, especially if you are using nightly version of some plugin rapidly evolving (yes, I’m looking at you, Scala plugin), you just have to throw out the “.metadata” directory which is on your workspace directory. You will loose all your preferences and project configuration, so don’t do this lightly. But sometimes, gains are astonishing. Ok, to be fair, other times, they are barely noticeable.

Configure your eclipse.ini settings

Eclipse’s main settings are set in the eclipse.ini file, in your Eclipse home directory – yep, the one you got when you unzipped that huge archive labeled Eclipse-something.zip.

If you never touched that file, it’s more than time to take a look at it and use sane settings.

Unfortunately, it seems that part of its configuration is more in the domain of cooking than of pure science. Eclipse is such a huge and versatile platform that there is simply no such thing as “good settings for everyone”.

Nonetheless, there is at least one setting that you have to change a little: give more memory to Eclipse. If you have a modern computer with something like 2 or 4 GB of RAM on it, you can spend more than 256 MB (default maximum size for Eclipse 3.5-SR2). So set the “-Xmx” parameter to 512 or 1024 MB (example setting below).

A lot of setting optimizations revolves around JVM tuning, so perhaps you could spend some time in the literature on that topic (see References at the bottom)

For the other ones, there are loads of examples on internet, as for example on StackOverflow :

-startup
plugins/org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar
plugins/org.eclipse.equinox.launcher.gtk.linux.x86_1.0.200.v20090520
-product org.eclipse.epp.package.java.product
-showsplash org.eclipse.platform
--launcher.XXMaxPermSize 384m
-vmargs
-Dosgi.requiredJavaVersion=1.5
-Xms128m
-Xmx384m
-Xss4m -XX:PermSize=128m
-XX:MaxPermSize=384m
-XX:CompileThreshold=5
-XX:MaxGCPauseMillis=10
-XX:MaxHeapFreeRatio=70
-XX:+UseConcMarkSweepGC
-XX:+CMSIncrementalMode
-XX:+CMSIncrementalPacing

But that doen’t mean that it will work well for you: these settings were awful for the way I use Eclipse – the CompileThreshold=5 seems to be a performance killer for me.

So, for environments with the Scala Eclipse Plugin and the Maven one, the best setting.ini I came up with is:

-startup
plugins/org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.gtk.linux.x86_1.0.200.v20090520
-product
org.eclipse.epp.package.java.product
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
384m
-vmargs
-Dosgi.requiredJavaVersion=1.5
-server
-XX:PermSize=256m
-XX:MaxPermSize=256m
-Xss2m
-Xms1G
-Xmx1G
-XX:MaxGCPauseMillis=10
-XX:+ScavengeBeforeFullGC
-XX:-UseParallelOldGC

The “-server” seems to be rarely set in eclipse.ini examples, and it seems to be a major improvement for me over -client. If not specified (nor -client), this parameter is chosen by default if you have more than two processors and 2 GB of RAM.

PermSize controls the size allocated to compiled classes and permanent data structure. Both Eclipse and Scala seem to make heavy use of it, so I chose to set it to a big, defined value.

Scala makes a heavy use of Stack, but perhaps you could leave Xss to its default value.

I like to set Xms/Xmx at the same value, and 1GB seems enough for what I’m doing.

-XX:MaxGCPauseMillis=10 is a tip to have the GC pause at most for 10 milliseconds. We’re not speaking about real time here, so it’s really just a hint time that can be exceeded, but the JVM will try to meet it – at the expense of increased memory usage.

Finally, the last parameter is the Garbage collector I want to use. Most of the time, Eclipse users advise to use the “Concurrent Mark Sweep GC“  that is designed for short pauses and should be better for the kind of application Eclipse is (you can see it in the first eclipse.ini snippet). But it seems that the “Parallel Old GC” works better for me. There is one other garbage collector, the “Garbage first CG“. It seems that it may be a major improvement, but (I really don’t know why), it also seems to make Scala compiler much slower, and so is a no-go for me. With that Garbage collector, the eclipse.ini file would look like:

-startup
plugins/org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.gtk.linux.x86_1.0.200.v20090520
-product
org.eclipse.epp.package.java.product
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
384m
-vmargs
-Dosgi.requiredJavaVersion=1.5
-server
-XX:PermSize=256m
-XX:MaxPermSize=256m
-Xss2m
-Xms1G
-Xmx1G
-XX:MaxGCPauseMillis=10
-XX:+UnlockExperimentalVMOptions
-XX:+UseG1GC

To conclude, I encourage you to learn about JVM tuning, and especially learn about Garbage Collectors. I only show three examples of them, but there are many more GC configuration possibilities and even more options for them. In the end, garbage collectors drive a lot of performance enhancements, so it is good to know how to optimize them.

References

Here comes some references about JVM tuning and Garbage Collectors:

Notes

[1] Well, if you were an IntelliJ or Netbeans advocate, you wouldn’t be spending your time reading blog posts about how to enhance a competitor, would you?

[2] Yep, that was a fairly random choice. Really. Launched a pair of dices, they said Maven. Forty-two times. In a row. Really.

[3] If you are not a developer or never felt what “being in the flow is”, perhaps PeopleWare [http://www.amazon.com/exec/obidos/ASIN/0932633439] or item#8 on http://www.joelonsoftware.com/articles/fog0000000043.html may help you understand why it is so important for us – and it also gives us a reason to have single-person office with big windows.

[4] But that is ok, it is also order of magnitude more powerful

[5] http://kthoms.wordpress.com/2010/02/20/first-experience-with-ssd-in-macbook-pro/

[6] http://java.sun.com/javase/downloads/index.jsp

Normation

87 rue Turbigo
75003 Paris

Tel : 01 83 62 26 96
Fax : 01 83 62 29 38
Contact us

Sign up for our newsletter

English
Français

Follow us