This is really two questions, but they are so similar, and to keep it simple, I figured I'd just roll them together:
Firstly: Given an established Java project, what are some decent ways to speed it up beyond just plain in-code optimization?
Secondly: When writing a program from scratch in Java, what are some good ways to greatly improve performance?
Please stay away from general optimization techniques unless they are Java specific.
I asked this about Python and Perl earlier. For Java I'm wondering what good tips/tricks are out there to improve performance and if there are any particularly good Java profilers.
-
For profiling, try JAMON for time monitoring, and the NetBeans profiler for general performance and memory monitoring.
From Nerdfest -
Using StringBuilder in place of large sets of String concatenation gives a great relative performance boost.
However, I can't avoid saying the general practice performance gaining benefit, Profiling. I don't know Java profiling off-hand (Only used the language academically), but profiling helps you identify problem sections of your code, and it is a lot easier to fix specific sections since you have something to look up.
skaffman : In many cases, the VM will turn string concatenation into StringBuffer manipulation. I'd be be surprised if doing this manually gave any performance boost except in the most bone-headed of cases.finnw : @skaffman, Don't confuse StringBuilder (unsynchronized) with StringBuffer (synchronized.)shadit : Since Java 5, the compiler turns String concatenation into the equivalent StringBuilder calls. If you write a trivial class with String concatenation in it, compile, and then open up the .class file in a text editor, you'll see the StringBuilder replacement calls.Michael Borgwardt : Neither the compiler nor the VM will replace string concatenation with StringBuffer when it happens inside a loop (i.e. a String scoped outside the loop is concatenated to inside the loop) - which is pretty much the only time where it really counts.From Guvante -
The same as for any language, use appropriate algorithms and data structures.
One good thing of OOP, is that you might be able to change implementations of an object without changing the interface. That lets you start coding with naïve implementations and replace them if needed.
From Javier -
Firstly : by code optimization, I would assume that you've done the right algorithms and right implementation of algorithms. In which case, you would use the profiler and look at how often your garbage collector(GC) is collecting garbage and how much time it is using for doing that. Then you start working on the GC options -- but beware you can get into trouble if you don't know what you're doing.
I assume that you're using java 5/6. In which case, I'd go through the java 5 tuning guide at http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html. There is also a very very good newletter on java performance called http://www.javaperformancetuning.com/ to which you can subscribe.Other than that, look at how many try/catch blocks you can eliminate. See if you can eliminate unnecessary throwing of Exceptions.
Use Caches where you can BUT don't over do it.
Read Effective Java, 1st and/or 2nd Edition
Profilers : I use yourkit. It's pretty good for java 1.5 and above. You can get a personal license. Other profilers are also good as well.
Just like you have unit and integration tests, it does NOt hurt to have some performance tests that you run as part of your CONTINUOUS INTEGRATION(CI) builds. This way you know when you regressed, especially if you are using a good CI build server.
Alex Miller : try / catch is fairly cheap these days. I wouldn't worry about that.sk : Note 'Caches' should not include object pools, which are not recommended these days except in the case of "expensive" objects like thread pools or database pools.From anjanb -
Use the latest VM--they are getting better all the time.
Profile and test. Never optimize your code unless you are absolutely sure you need to.
If it's a GUI app, Switch from Swing to AWT or maybe Eclipse's toolkit, it's supposed to be pretty quick. This is more important on older VMs (I've been working embedded for a while and we are actually in a 1.0.x vm, swing isn't even available)
I know this isn't specific to Java exactly, but not allocating objects--this includes string concatenation in a loop (outside a loop it's pretty acceptable. This is the biggest thing you can probably do.
You can also keep objects around instead of freeing/reallocating them. There are some "reference" classes that can be used to hold onto objects that you don't need but might want to reuse--the GC won't delete them unless it needs the space.
Allocate more space if needed with the -MX argument.
It's kind of hard to speed Java up much--HotSpot already does so much for you that anything you do that you think might speed up your code can often slow it down.
Roland Schneider : Rendering in Swing is not that slow. Most of the time it's the business code that blocks the EDT.Bill K : Good point, but I did actually have a 1.1 embedded project (Signal analyzer for Agilent) where the GUI was in AWT, we re-coded it in swing, then found that swing was significantly slower and we re-coded it in AWT. This is a case where we were actually drawing the trace for the signal analyzer and needed at least 20 fps.From Bill K -
Make sure your log level's aren't accidentally left at DEBUG :)
agnul : Accidentally. Yeah, right! :-)Christian Vest Hansen : It is amazing how big a difference this can do.From matt b -
"Measure, don't guess."
Here is a good article on using the NetBeans Profiler to speed up the iText PDF library. I've used the NetBeans Profiler myself, and I've found it to be very easy and useful in tracking down some performance issues I was having.For an older application, simply moving to Java 6 might be a performance boost. See this whitepaper for information on the performance improvements in Java 6.
From Michael Myers -
I've seen that sometimes just giving the JVM more heap memory will help a sluggish application. This is controlled with the
-xmx
and-xms
JVM options at startup.jlouis : Happens because you are close to exhausting the heap space and thus have more garbage collections to attempt a clean-up. You can either increase heap space as you suggested or find the culprit that is taking up all the memory.From Vinnie -
Another potential performance gain can be realized by switching to a faster VM. They are not all made equal, and some are better suited to different types of applications. They may also each have specific types of customizations that they support, as well as the standard ones.
Also, be wary of doing microbenchmarks for testing performance, as they are not meaningful due to the way most VM's work. So some very simple performance tests may behave differently due to reasons that are not obvious.
Simply running a test and then changing a small bit of code or a VM option and running it again, may produce different results, but have nothing to do with the changes you made.
From Robin -
There's one thing you should do right from the start of a project that will be an enormous help: write readable code.
Don't try to write long methods to avoid method calls. Compilers will inline if necessary, but may produce poor code for long methods. If the code is difficult to read, often performance problems will be caused by it doing something mental that you can't see for the clutter.
-
Java 1.6_07+ comes with its own profiler. It is called Java VisualVM. Just type jvisualvm on the command prompt if you have your %JAVA_HOME%/bin on your PATH.
StaxMan : All JVMs since at least 1.2 have come with in-built profiler (-Xrunprof:cpu=samples or such on command line). Visualization part may be new.From Joshua -
Here is an (older) document by Peter Sestoft which is worth reading: Performance in java. Some of the advice is probably not true anymore since Java got a lot better with the later versions in optimizations. But there are still a good set of gems in there to utilize and try when the profiler has found something you can't do any other way (ie, change algorithmically).
From jlouis -
Don't optimize blindly. Use Yourkit or any other good profiler to find out the "hotspots" in your application.
You need not only take a look a CPU time, but also at how much memory is allocated and freed for certain step. You also want to ensure that you don't have memory leaks, or high memory consumption. The best tool to analyze memory consumption that I know is the Eclipse Memory Analyzer (http://www.eclipse.org/mat).
Other dimensions are thread contention and IO problems. For a simple way to analyze contention problems, check my old blog at https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/4737
From kohlerm -
You also asked this in regard to C#, and I would give the same answer, and that it's a mistake to start off being language-specific. Once you've squeezed every cycle that you can get using general techniques and approaches, then language-specific stuff might make a difference.
From Mike Dunlavey -
It may seem irrelevant, but there is a list of speed tips on the Android developer site. It's running on a phone on non-standard dalvik bytecode but many of the tips listed there are universally applicable to Java in general.
From izb
0 comments:
Post a Comment