Is Java really slow?
Java has some degree of reputation for being slow.
- Is Java really slow?
- If yes, why? Where is (or was) the bottleneck? Is it because of inefficient JVMs? Garbage collection? Pure bytecode libraries instead of JNI-wrapped C code? Many other languages have these features, but they don't have this reputation for slowness.
Solution 1:
Modern Java is one of the fastest languages, even though it is still a memory hog. Java had a reputation for being slow because it used to take a long time for the VM to start up.
If you still think Java is slow, see the benchmarks game results. Tightly optimized code written in a ahead-of-time compiled language (C, Fortran, etc.) can beat it; however, Java can be more than 10x as fast as PHP, Ruby, Python, etc. There are specific areas where it can beat common compiled languages (if they use standard libraries).
There is no excuse for "slow" Java applications now. Developers and legacy code/libraries are to blame, far more than the language. Also, blame anything 'enterprise.'
In fairness to the "Java is slow" crowd, here are areas where it is still slow (updated for 2013):
Libraries are often written for "correctness" and readability, not performance. In my opinion, this is the main reason Java still has a bad reputation, especially server-side. This makes the String problems exponentially worse. Some simple mistakes are common: objects are often used in place of primitives, reducing performance and increasing memory use. Many Java libraries (including the standard ones) will create Strings frequently, rather than reusing mutable or simpler formats (char[] or StringBuffer). This is slow and creates tons of garbage to collect later. To fix this, I suggest developers use primitive collections and especially Javalution's libraries, where possible.
String operations are a bit slow. Java uses immutable, UTF-16-encoded string objects. This means you need more memory, more memory access, and some operations are more complex than with ASCII (C, C++). At the time, it was the right decision for portability, but it carries a small performance cost. UTF-8 looks like a better choice now.
Array access is a bit slower compared to C, due to bounds checks. The penalty used to be big, but is now small (Java 7 optimizes away a lot of redundant bounds checks).
Lack of arbitrary memory access can make some I/O and bit-level processing slow (compression/decompression for example). This is a safety feature of most high-level languages now.
Java uses a LOT more memory than C, and if your application is memory bound or memory bandwidth bound (caching, etc.) this makes it slower. The flipside is that allocation/deallocation is blazing fast (highly optimized). This is a feature of most high-level languages now, and due to objects and use of GC rather than explicit memory allocation. Plus bad library decisions.
Streams-based I/O is slow due to the (IMO, poor choice) to require synchronization on each stream access. NIO fixed this, but it is a pain to use. One can work around this by doing read/write to an array, instead of an element at a time.
Java doesn't provide the same low-level functionality C does, so you can't use dirty inline assembler tricks to make some operations faster. This provides portability and is a feature of most high-level languages now.
It is common to see Java applications tied to very old JVM versions. Especially server-side. These old JVMs can be incredibly inefficient, compared to the latest versions.
In the end, Java was designed to provide security and portability at the expense of some performance, and for some really demanding operations it shows. Most of its reputation for slowness is no longer deserved.
However, there are several places where Java is faster than most other languages:
Memory allocation and de-allocation are fast and cheap. I've seen cases where it is 20% FASTER (or more!) to allocate a new, multi-kB array than to reuse a cached one.
Object instantiation and object-oriented features are blazing fast to use (faster than C++ in some cases), because they're designed in from the beginning. This is partially from good GC rather than explicit allocation (which is more friendly to lots of small object allocations). One can code C that beats this (by rolling custom memory management and doing malloc efficiently), but it is not easy.
Method calls are basically free and in some cases faster than large-method code. The HotSpot compiler uses execution information to optimize method calls and has very efficient inlining. By using the additional execution information, it can sometimes outperform ahead-of-time compilers and even (in rare cases) manual inlining. Compare to C/C++ where method calls come with a small performance penalty if compiler decides not to inline.
Synchronization and multi-threading are easy and efficient. Java was designed to be thread-aware from the beginning, and it shows. Modern computers usually feature multiple cores, and because threading is built into the language, you can very easily take advantage. Basically an extra 100% to 300% speed boost vs. standard, single-threaded C code. Yes, carefully written C threading and libraries can beat this, but that's a lot of extra work for the programmer.
Strings include length: some operations are faster. This beats using null-delimited strings (common in C). In Java 7, Oracle took out the String.subString() optimization, because people were using it stupidly and getting memory leaks.
Array copy is highly optimized. In the lastest versions, Java uses hand-tuned assembler for System.arraycopy. The result is that in arraycopy/memcopy-heavy operations, I've seen my code beat the equivalent in C by reasonable margins.
The JIT compiler is smart about using L1/L2 cache. Ahead-of-time compiled programs can't tweak their code in real-time to the specific CPU & system they're running on. JIT provides some very efficient loop transformations this way.
A couple of other historical facts contributed to the "Java is slow" reputation:
- Before JIT compilation (Java 1.2/1.3), the language was only interpreted, not compiled, and thus very slow.
- JIT compilation took time to become efficient (major improvements with each version)
- Classloading has become a lot more efficient over the years. It used to be quite inefficient and slow during startup.
- Swing and UI code did not use native graphics hardware very well.
- Swing is just awful. I blame AWT and Swing for why Java never caught on for the desktop.
- Heavy use of synchronization in library classes; unsynchronized versions are now available
- Applets take forever to load, because of transmitting a full JAR over the network and loading the VM to boot.
- Synchronization used to carry a heavy performance penalty (this has been optimized with each Java version). Reflection is still costly, though.
Solution 2:
Initially Java was not particularly fast, but it is not overly slow either. These days, Java is very fast. From the people I've talked to the impression of Java being slow comes from two things:
Slow VM startup time. The early Java implementation took a long time to start up and load the require libraries and the application compared to native applications.
Slow UI. Early Swing was slow. It probably did not help that most Windows users found the default Metal L&F ugly either.
Given the above points, it's no wonder people got the 'Java is slow' impression.
For users or developers used to developing native applications, or even Visual Basic applications, these two points are the most visible thing in an application, and it is the first impression you will get about an application (unless it's a non-GUI application in which case only the 1. applies.).
You will not convince a user that "it executes code very fast" when the application takes 8 seconds to start vs. his old Visual Basic application that starts immediately - even though code execution and startup time might not be connected at all.
Ruining the first impression is a great way to start rumors and myths. And rumors and myths are hard to kill.
In short, Java is not slow. People having the "Java is slow attitude" is based on first impressions of Java more than 10 years ago.
Solution 3:
After reading a page full of comments saying Java is not slow, I just have to answer with a differing opinion.
Slowness of a language is a lot dependent on what your expectations are for 'fast'. If you consider C# to be fast, Java surely is fast too. If your problem domain is related to databases, or semi real-time processing, Java is surely fast enough too. If you are happy to scale your application by adding more hardware, Java is likely fast for you. If you consider that a constant factor speedup in the scale of 5-10 isn't ofter worth it, you likely consider Java fast.
If you do numerical computation on large data sets, or are bound to an execution environment, where CPU resources are limited, where a constant speedup in the scale of 5-10 would be huge. Even a 0.5 speed up might mean a 500 hour reduction for the computation to complete. In these cases, Java just does not allow you to get that last yard of performance, and you'd likely consider Java to be slow.