The JVM once again causes controversy when evaluating Java's speed. Java benchmarks typically discount the startup time of the JVM itself. Non-Java benchmarkers would consider this unfair, and not fully representative of the overall program performance. It's a difficult debate. If I want to simply compare, say, raw Java Vector performance versus raw C++ STL vector performance, then why should we consider start-up times? Also, if I'm trying to profile algorithms within my program, again, why should start-up be useful in evaluating? But, if I'm comparing two programs that perform an equivalent task, I'd probably want to consider the overall time from initial execution to completion. Having said that, the larger the application, the less of an issue the JVM load times will be due to economies of scale. (Note, even this is getting better thanks to Class Data Sharing, amongst other things) One other thing to remember is that many Java applications are actually deployed as a Jar file (a glorified Zip file, essentially). You can execute the code within from the JVM directly - it therefore has to decompress the file first, and this obviously incurs a time penalty.
The Project Barcelona research group at Sun are coming up with some interesting technologies to improve the JVM in the future. That's not to say that the current JVM hasn't been improving steadily during each release. The Multi-tasking Virtual Machine (MVM) looks most promising as it'll allow multiple Java applications to share the VM, reducing the overall burden on system resources. Ok, I know you can do this already on the current JVM, but it's still a little raw. The MVM will be much more scalable and efficient. It seems to me that with such a system, you can finally run the JVM as a daemon on your system at startup, and then all subsequent Java programs you load will load as quickly as native apps. One can't help but lose some optimism when you learn that the MVM may not even make it into Java 1.7 (Dolphin) due in the second half of 2007. I hope it does! In the meantime, you could to better than to look at some of the existing shared VMs like Janos, JKernel and Alta.
It's on the desktop where many people form their opinions of Java, and it is here where people complain most about performance issues. The Swing toolkit is very powerful and rich, yet it is huge. Werner Randelshofer states that a Swing "Hello world!" program will require approximately 800 classes to be initialised before the user sees the infamous greeting. Yet, there is no shortage of Java developers who will tell you that Swing is fast.
What those in the know will tell you is that Java in fact has a problem in perceived performance. You often hear about grey rectangles, unresponsive widgets, etc. The issue here is that Swing is perfectly responsive, until you hit a widget that triggers a task. The biggest trap Swing programmers fall into is that they don't understand the threading model that is employed.
Here's the science...
The Java designers decided not to make Swing components thread-safe, and instead opted for a single thread (known as the event-dispatch thread), to maintain the state of the GUI components. Therefore, your code that you want to run when a user clicks on a given button by default gets added to the EDT. If the code is something non-trivial, like loading a large file or querying a database, then this will block the EDT until it completes, resulting in an unresponsive GUI in the meantime. The remedy is to dispatch long tasks (i.e., anything likely to take > 0.25s) on their own thread, which frees up the EDT for doing purely GUI related tasks (see Ben Galbraith's excellent tutorial).
The EDT approach is hardly exclusive to Java because it makes toolkit design much easier. You'll find .Net's Winforms opts for a similar model. The EDT is supposed to simplify things, yet it seems to be a common pitfall. Some one commented recently:
"... I may point out that Swing is not slow... The problem is that's very easy to shoot yourself in the foot with Swing, but can happen with any toolkit, even those using native code. Well written Swing code can be as fast as a native application, if not faster."
Shooting yourself in the foot
I was interested in this comment and decided to go off at a bit of a tangent here to examine if Java is really that prone to making unresponsive interfaces. I was discussing this with Jasper Potts from Xerto (producer of the visually impressive Java app, Imagery) and we got on to documentation:
"Swing itself is not slow, but that's not to say that it's that easy to write large applications that perform well. There is definitely room for some more articles on using Swing in the desktop... There is a real need for Swing books that tell you how to do things in the real world. [Desktop Java Live] is the first book I have come across that is trying to do that. Even all the books called "Advanced ...","Extreme...", etc., all they do is redo the Java [API] docs for the more advanced components. There are a few topics that just don't seem to be documented at all well anywhere like the Focus System."
"Java/Swing being slow is one of those myths that has become embedded in the mindset of developers. I can easily write a desktop application in any language that is slow. I would suspect that 8 out of 10 developers that comment "Swing is slow" haven't written a Swing app in at least 5 years. It is much like the Linux developer community labelling Microsoft as evil. Even if Microsoft became the best open source citizen tomorrow, it would take many years before the majority of developers would have this opinion of them. As far as countering the statement, I think the best rebuttal is the continuing production of quality desktop applications written in Java. The more there are the harder it is to argue against them."
DJL devotes an entire chapter to threading in Swing. I asked Scott whether he thought threading was a common pitfall for Java Swing developers and therefore was it something inherently wrong with Java's design:
"Anyone that is a software developer gets paid for a reason. Software development isn't something that you can master in a three day correspondence course. I've always felt that it is each developer's responsibility to become competent with the features of the language/toolkit they are developing with. Threading is a core part of writing desktop applications. You can easily find discussions about desktop threading on the Internet in regards to numerous other toolkits. It makes no sense to me when people complain about threading in respect to a language. No one complains they have to learn OO to use Java or for-loops to use .NET effectively. In regards to Swing specifically, it is designed very similarly to other common UI toolkits. If you look at QT, GTK, SWT, .NET, etc., you will see they all use some variation on the single event thread concept. Some have the concept of a global lock, however I'd much rather have the ability to address such complexities myself than a brute force approach supplied for me. I will concede that a few more threading utilities built into the core of Swing might help new developers. However, open source projects such as Foxtrot, Spin, and SwingWorker address a large portion of Swing threading related issues. Relating back to my earlier point, I think it is the responsibility of good developers to become aware of the tools that can enhance their development process."
An interesting point here is that other UI toolkits use this threading model, but you rarely hear that these toolkits are slow. Yet, I have seen examples for most which also block the thread and therefore become unresponsive. I think Java has had some bad luck in that its legacy has stuck. Nowadays though, I do believe that if you see a slow Java application, the fault lies at the developer's door, and not Java. For example, Eclipse had recently come under fire for becoming slow - especially with its start up. Critics automatically assume that this is because of Java. In its most recent M7 milestone release they significantly improved performance - a bottleneck being the plugin framework that Eclipse relies not being very scalable for increased numbers of plugins. The point being that this is an algorithmic issue - one that could have occurred in any language, yet it seems to become a Java issue. Of course, some more prominent articles and examples covering common pitfalls would certainly help to ensure new UI programmers get good performance from the outset.