Not to directly pick on Peter Bell at all (he’s a very smart guy and I really enjoy his blog, so this is nothing personal at all), I just noticed something he mentioned in a recent comment on a blog entry and felt that it was something I should address in a blog post rather than a comment. Also, writing this entry gives me a good reference point later to send to people when they present the same talking point to me.
Anyhow, here is the comment that Peter made which inspired this blog entry (which in context, is a quip):
I also have to question why you’d even consider using CF for a performance critical app - even Java is a little sluggish. If you want bare metal performance and think your time is worth less than the cost of a server, go for it and write the darn app in C++!
I wanted to point out and correct a common fallacy that I see repeated over and over again are statements rooted in comments like “If you need speed, you could convert your Java application to C or C++”. I don’t claim to be a Java expert by any means, but I do think I have a good enough understanding of the Java platform as well as basic operating systems & compiler theory and the like to explain why this is a false argument. The answer is actually more along the lines of “it depends on what you are doing”, and I’ll explain why.
It’s very easy to see where this misconception started– pretty much every software developer or system administrator has encountered a slow Swing/AWT based Java application which took forever to start, and generally seemed pretty sluggish. Not to mention it probably looked terrible. One of the best Java based desktop applications, Eclipse, even takes awhile to start. On the contrary, C++ desktop applications typically start very quickly, and are very responsive to user input. Generally speaking the symptoms of running a Java desktop application match the reality– C++ is almost always faster for short running programs such as desktop applications.
Another common assumption is that it would seem that the JVM itself is an abstraction above machine level code because it acts as an interpreter, and that C/C++ will always be faster because the resulting compiled code is “closer to the hardware” which is also false. In the early days of Java, the JVM did in fact interpret code, but eventually it started using a Just In Time compiler in Java 1.2 to compile the code down to the machine level. Different implementations of the JVM use various JIT compilers, but the Sun JVM uses the HotSpot JIT. Not only are Java programs compiled down to machine specific code, but the longer a program runs, the better it gets optimized.
The HotSpot compiler monitors and analyzes an applications performance over time, and uses adaptive optimization to eliminate bottlenecks in the machine code, known as “hotspots”. It essentially looks for pieces of code that are ran time and time again, and marks them for optimization. Those pieces of code are then recompiled again into machine specific code for performance. This allows for ongoing performance enhancements that you would never get from machine code produced by a C or C++ compiler such as branch prediction hints.
All of these things are not just unfounded theory, there have been several independent studies about this including this one by the University of Southern California.
Java is now nearly equal to (or faster than) C++ on low-level and numeric benchmarks. This should not be surprising: Java is a compiled language (albeit JIT compiled).
This study is several years old now and doesn’t include testing against the many performance enhancements which were made available in the 1.5 JVM, so I’d be interested in seeing an updated study.
That said, Java is probably much faster than you think. One way I’ve seen the Hotspot compiler in action (and you can try at home) is when working on a simple “Hello World” JSP and keeping track of it’s execution time. Typically on the initial run or two, the JSP page is pretty quick, but then after a few calls of the page the Hotspot compiler kicks in and makes it wicked fast so that it’s execution time is effectively nil.
Now that we’ve spoke to the “Java Is Slow” audience, we should cover the answer to the earlier question of “Is Java slower than C/C++?”. This is more of an “it depends” answer. Generally speaking C++ has the advantage in short running applications, and Java is as fast if not faster than C/C++ in long running applications such as servers, web applications, etc. It also might surprise you to know that Java is also very good in real time systems, but that is another blog post of its own.
17 Responses
Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.
It should be noted that this comment by Peter was somewhat facetious.
Yep, for sure, I guess I should make that a little more clear, although it’s hard to tell if he was kidding about the “close to the hardware” part. I’m sure he’ll stop by and comment soon enough.
It’s a topic I’ve wanted to cover before, I just thought I’d mention what had influenced it.
Good post.
Hi Brandon,
Many thanks for posting this! I remember reading something like this a few months back and it makes perfect sense to me. I think I read something similar quite a few years back showing that the best C compilers beat hand written machine code almost all the time despite the protestations of the “if it isn’t assembler it isn’t real coding” crowd.
As compiler design continues to improve, I think the performance penalty between languages will continue to decrease. Look at Lisp - it was based on a form of mathematics that was never really supposed to be a working language at all and yet now it performs well enough to be a plausible language choice for a number of real world use cases!
The truth is that I’m pretty ignorant about these kind of performance tuning issues because they are irrelevant to my clients who typically have lightly loaded apps, but it does seem strange to me for people where performance is much more important than their time to be choosing CF as their dev language. At the very least I’d just write the app in Java if I was that concerned about performance.
Toooooooo good post. Being a Java fanatic, this really makes my day.
Good post, Brandon. Unfortunately, facts rarely get in the way of a good myth.
I read a while ago (might have been a few years ago) that one possible source of this perception is poorly-written apps, especially Swing apps, using threading poorly or not at all.
Unfortunately, I think this myth is going to be a hard one to put to bed…look at Paul Graham - he’s been fighting the “Lisp is for AI” myth for a while, and that hasn’t exactly been put to bed, either.
Not to mess up your good time, but there are reasons why Java can not be faster than C++ in many ways:
- All objects in Java are allocated on the heap; in C++ you can choose to allocate them on the heap, stack; for very fast ops, even register allocation class is used
- All functions are virtual which means at least an indirection to a table of function pointers.
- It is very hard for a compiler to automatically optimize to the level that a good developer can optimize (inline functions, placing the most cost effective ‘ifs’ first, etc).
Granted that this doesn’t matter for a JSP or a SWING application, but if you are writing server applications or some other complicated application (like a game or operating system modules, or device drivers, etc), Java is not good enough.
Think that C++ was arround for 30 years now and there are a lot of heavy applications written in it. It will definetly evolve - it did over time - as an open standard and not something controlled by a corporation.
And in the end, it is not really a discussion between C++ and Java - not anymore. Now, various componens of an application can be written in the language that helps you achieve faster the desired result. For websites, some may argue is PHP
What matters most is the bottom line, which is the “user experience.” From the user perspective, Java is slow or sluggish or anything but impressive and quick. That’s what matters in the end. The day Java applications seem quick is the day it can be argued that Java is not slow.
While I have little experience in Java programming, as C/C++ and C# are my main languages of choice, I have done some Java programming before. Being a user and a java programmer (albeit nothing serious) I can see how people can get the impression that its slow. Java apps have been, in past experiences, a little sluggish compared to C++ applications. They just don’t respond as quickly and feel lethargic to use.
IMO, I think .NET has the upper hand over Java and its class framework. We’re seeing more and more .NET based websites using asp.net, c#, vb.net etc which are very fast because of the CLR and JIT.
I see what you saying but the JVM cannot replace a good programmer and it can’t make a bad program better or faster or more optimize. Even saying that it can ever be faster than C++ is like saying that it can be faster than assembly. The problem with java is that there is just too much going on in the background too much “magic”. in todays “what you see is what you get” world if it looks slow people are going to say its slow. Who wants to wait 2 hrs for the JVM to optimize itself?
Its better to stop comparing it C++ and look for more comparable cross platform languages.
I dont agree. Look at JVM, it is itself written in c/c++. Can we ask why not was it written in Java? If you wrote it in java, wouldnt it be faster to develop and have less bugs too (and less testing time)? Well its just that its not *fast* enough for this job! JVM is a very very critical application. No matter what language produces the byte code, its the JVM that gives you the end performance impressions and which can not be compromised, SO: write it in C++. Now I dont see Java speed getting *better* with time, what I see is that the *processors* are getting faster. Now v have quade cores available. You run the same app of java on a multi core proc machine and it’ll run faster and in the next few years java ppl are going to be saying “oh look we have become so fast” and “lets write the JVM in java too!”. And u’ll simply have a jvm in java *not* because java would have become faster, but because machines will be able to run the code faster. And at that time even, c++ will blow the pants off java if you’ll dare compare it again
cheers …
Java is slow!. I am 100% sure of that. Even if you optimize every possible way , it will be slower than c or c++. Also it is easy to make java slow than c++. Bad coding and bad architecure is the problem. Java will never close to c++ in fast response initially but can pick it up once it is in memory. So initial user experience is the one that counts. Java is slow. Period.
Every webpage with .jsp extension is slow compared same “concept” asp. So there is also problem in the way server side technology implementation. You need extremely sun fast servers to make jsp file to respond faster. That said t, growth of Java makes microsoft work harder, otherwise they will be continue to give us buggy technologies. I think WPF concept from microsoft will be very successful.
Re: Comment by Abubakar — September 27, 2007 @ 8:35 pm
Sorry I know this is closed, but I don’t understand how you could possibly write a JVM in a language that needs a JVM… Seems like ‘turtles all the way down’ argument…
Abubakar: You can’t write the JVM in Java, because you can’t run it without having a JVM. To write the JVM in Java, you’d have to run another JVM to house your first JVM. But then you get infinite recursion, which would actually hamper your performance.
I did a recent benchmark myself just as a quick test (I’ll post it myself eventually), between Java and C++. The benchmark in question was “calculate all the prime numbers between 2 and n using the seive-primes method”.
Seive-prime method: Have a boolean array of size n, with all elements true. Starting at i=2, for each entry, if the array is true, set all multiples of i to be false and output i, which is prime. This will list all the primes in that range.
The machine in question was running Ubuntu-8.04 on a T5400 CPU with 2GB of RAM. I used System.nanotime() in Java and the time command in C++ to arrive at the final times. Java was run with jre-1.6.0.6 from Sun, while C++ was compiled with g++ -O3 (-O3 = optimize as much as possible). The code between the two languages is near-identical, save that I actually had the option for file I/O in Java, and of course { inline, public static vs. outside-of-class functions }; I have yet to add const/final keywords, but will do that sooner or later.
The conclusion is this: Java and C++ performed exactly the same. With n set to 100000000 (that’s 100 million), both took about nine seconds. The difference was on the order of milliseconds. Interestingly, even when writing to a file, Java took nearly the same amount of time (an extra couple hundred milliseconds), despite producing a 50MB(!) file.
Continuing the Discussion