share
Stack OverflowIs Java really slow?
[+180] [19] Stefano Borini
[2010-01-29 16:39:24]
[ java performance ]
[ https://stackoverflow.com/questions/2163411/is-java-really-slow ]

Java has some degree of reputation for being slow [1].

(35) people get so nervous... don't see how this can be subjective, nor it's argumentative. I wonder if a question like "why bubble sort is slow" would obtain the same result. I asked a technical question, and wanted technical answers (which I got), but closing the question as subjective and argumentative is ridiculous. - Stefano Borini
(1) I have read most of the top comments and none of them seem to address the glaring fact that C# GUI-based desktop applications run much faster than any Java GUI-based desktop applications, including modern ones. - BobTurbo
(3) As a client-side web dev who has dealt with .net webforms, .net MVC, PHP, Rails, Django and a wide variety of everything but Spring (which I've heard is good) in Java, I expect poor performance/architecture from back ends built by Java teams. I suspect the real problem isn't benchmarks but rather the issue of there simply being a crap-ton of mediocre Java devs out there. That's not the language's fault. It's not the fault of Java devs who actually hone their craft and learn languages other than Java. It may however be the fault of Sun, certs, the '90s, and the IT industry in general. - Erik Reppen
[+236] [2010-01-29 17:00:56] BobMcGee [ACCEPTED]

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 [1] 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 [2]-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 [3] 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 [4] 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 [5] 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 [6] 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 [7] 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 [8] 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 [9] 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.
[1] http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?test=all&lang=all&lang2=gcc&data=u64q
[2] https://en.wikipedia.org/wiki/UTF-16
[3] http://en.wikipedia.org/wiki/UTF-8
[4] http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29
[5] https://en.wikipedia.org/wiki/Non-blocking_I/O_%28Java%29
[6] https://en.wikipedia.org/wiki/HotSpot
[7] https://en.wikipedia.org/wiki/CPU_cache#Multi-level_caches
[8] http://en.wikipedia.org/wiki/Swing_%28Java%29
[9] http://en.wikipedia.org/wiki/JAR_%28file_format%29

(49) Object instantiation and object-oriented features are blazing fast to use (faster than C++ in many cases) because they're designed in from the beginning. and Collections are fast. Standard Java beats standard C/C++ in this area, even for most optimized C code. are wild claims unsupported by any evidence linked here. - Sjoerd
(8) @Sjoerd - The claims are hardly wild--they're obvious to me, and should be to anyone who understands the differences in the architecture of the default memory system in C/C++ vs. Java. You can do much better still if you write your own memory handlers (with things like free lists, memory pools, and so on) or use a library that implements such. - Rex Kerr
(15) @Rex Kerr - Why use memory handlers if you can use e.g. the stack for allocation?! You are confusing heap memory allocation with object instantiation. - Sjoerd
(2) @Rex Kerr - The original Java collection classes had to be redesigned because the decission to make them thread-safe turned out to be a performance problem. The new collection classes were lightning fast compared to the old, but I can't see any reason why they would be faster than their C++ counter parts. - Sjoerd
(1) @Sjoerd - The stack is small and used for the call stack. You don't want to place your collection memory there, for example. In many cases you can't use the stack. And Java collections are fast compared to C++ collections due largely to the different memory subsystem. - Rex Kerr
(20) @Rex Kerr - Basically you are claiming that because everything in Java involves allocating memory on the heap, and because Java's allocation on the heap in Java is faster than C++'s, everything in Java is faster. Here is some news for you: in C++ you can do without allocating memory on the heap in many cases! - Sjoerd
(10) @Sjoerd - Where did I say that everything in Java is faster? Just read what I said. I said what I meant, and have already addressed everything you said in your last comment. - Rex Kerr
(5) Array copy is highly optimized. In the lastest 1.6.x versions, Java uses hand-tuned assembler for System.arraycopy - That means java uses a C/C++ version of arraycopy... which by the way means that it's as fast as one C or C++ version, not faster. It's like Javascript V8 regex engine supposedly beating C when it uses a C lib to make the regex possible - that's just one C implementation beating another. - Morg.
(2) Show me one serious and complex Java GUI app which does not totally suck performance-wise. For example, Azureus totally sucks performance wise. It's the only serious Java app I actually tolerate, because it is featureful, not too buggy, and works well, I can put up with the atrocious performance. - Sam Watkins
(2) A couple of notes: You can use sun.misc.Unsafe for arbitrary memory access, in a 64-bit JVM Java uses 32-bit references by default whereas a 64-bit C application uses 64-bit references and sizes by default. This can mean C using more memory. You can write your own ByteString class if being more compact is essential. I have written a library which supports persisted messaging between processes with a latency of 100 ns or less via memory mapped files. This is usually fast enough. - Peter Lawrey
(1) @Sam Watkins: The Android operating system? Java GUI performance can be bad or good, just like anything else it depends on how it is used. I'll agree that the Swing libraries are awful though. - BobMcGee
(2) Waiting for the VM to start up used to be slow? Are you kidding me? Just compare restarting Tomcat to restarting any other application server written in any other dynamic language. I really mean any other. And let's not start on memory usage. - Tobia
(2) @Tobia The question is whether the problem is Java itself, or the Java application server ecosystem. More than half of the world's smartphones run Java (Android) apps, and don't see a lot of complaints about startup times. I'd argue that the problem is the way the Application Servers are written. - BobMcGee
(2) ARM's ThumbEE (Jazelle RCT) has a hardware array bounds check instruction, which is a nice boost for mobile devices. Also, something to add to the list of Java pluses is JIT compilation based on the current architecture and actual runtime characteristics. - Jason C
@Tobia: Also, Java Application servers have gotten fast to start now -- antoniogoncalves.org/2011/10/20/… (3 seconds is common, under 15 seconds for all of them). When you throw apps into the mix, it goes up, but not by much: even on a slow dev VM, I can restart and redeploy the full set of SoA services (40 complex services, several hundred MB of EARs) for a billion dollar company, in a few minutes. - BobMcGee
(3) @BobMcGee Computers, not Java, have gotten faster. Why don't you compare those figures with, say, Python's Django, Ruby on Rails, Node.js, and all the others? If you want to include languages with a compilation step, you can even compare with Go. Two seconds to start up on modern hardware is a horrendously long time. 15 seconds is not even conceivable for anything that is not called "Java". - Tobia
@Tobia: if you can provide a reasonable comparison of startup times for those environments, and I will include it in the answer. Given that an application server is close to an operating system these days, I think a little time is understandable (disk I/O could be a big part of start-time, for example). Personally, I blame the big problem here on anything "enterprise." - BobMcGee
(1) @BobMcGee: This is a good answer but the main reason I perceive that Java is slow is its Lisp-like uniform data representation and lack of value types and reified generics. Indeed, that is why Java can be 17x slower than alternatives today: fsharpnews.blogspot.co.uk/2010/05/java-vs-f.html - Jon Harrop
@Sjoerd A long time after the fact. But, the JVM can be faster at object instantiation due to a problem for long-lived programs known as "Heap Fragmentation". The JVM does not suffer this problem due to the "Generational Copying" GC techniques that HotSpot uses. It also means that the JVM is much faster at 'freeing' memory since it doesn't free individual objects. Rather it moves survivors out of a block of memory and then marks the entire block as free. - Dunes
1
[+49] [2010-01-29 16:49:42] nos

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:

  1. 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.

  2. Slow UI. Early Swing [1] 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 [2] 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.

[1] http://en.wikipedia.org/wiki/Swing_%28Java%29
[2] http://en.wikipedia.org/wiki/Visual_Basic

why the longer startup time ? Please don't be afraid to be technical. What I don't get I will look up once I have the keywords. - Stefano Borini
(3) Java was very slow a few years ago but in recent benchmark tests it runs nearly as fast as C/C++ and in some situations it runs faster. - ChadNC
Startup times are quick nowadays. It was slow years ago, which was implementation details - e.g. the jvm loaded/decompressed almostthe entire standard library - not just the stuff the app needed - Anonym
ok, so basically the startup time was dominated by the repeated decompression of the whole library. but then I don't get another thing. Why did it have to be decompressed anew every time ? - Stefano Borini
(23) Java apps on OSX 10.6 on my Macbook start much slower than apps written in Objective-C. What evidence for quick startup times? - Zan Lynx
@Zan ok but if java has to start up a non-memory resident JVM anew, even with optimizations, it will never be as fast (in startup times) as a native Obj-C code which hooks into most likely preloaded libraries of OSX. - Stefano Borini
@Stefano on decompression: they reduce redundant decompression, and reduce the amount that is loaded in recent builds. Java 7 will provide modularity, so you only load a tiny part of the library, and should provide startup times comparable to normal apps. Unfortunately, Java 7 is showing no signs of ever being released. - BobMcGee
(2) Decompression is absolutely not a performance problem. My computer in 1992 decompressed executables when starting programs which improved performance over loading a longer file from the hard drive. The disparity between CPU and hard drive has grown enormously over the intervening years. However, there is a problem with using the zip archive format for rt.jar (why?!!!) and the contained class files are not linked (nuts!!). - Tom Hawtin - tackline
@Tom: You need to distinguish between compression algorithms. LZF, LZF, and LZJB are fast enough to improve on disk performance, and these are what you encountered in 1992. They're specifically designed to trade lower compression for very fast compress/decompress speed. DEFLATE is not designed for speed. While the CPU cost for ZIP has become less significant (and negligible on bleeding-edge CPUs) it still takes significant time when we're talking about multiple MB. Taking this another step: MP4 and LZMA are still very slow to compress/decompress even on modern CPUs. - BobMcGee
(5) @Zan: note that the JVM for Mac OS X is written (or at least adapted) by Apple. Sun has invested quite some time to make startup times faster on the platforms they support (Windows, Linux and Solaris), but they couldn't do it for Mac OS x (since they don't maintain that port). It might be that Mac couldn't/didn't apply/port all those optimizations over to Mac OS X. - Joachim Sauer
(1) I don't consider java to be slow (i know of a game maker who makes games in them); just bad for UI reasons. Not a single "regular" java app i've seen has a decent, completely working UI. - RCIX
@RCIX: You've never seen Eclipse? Lotus Notes? OK, bad example. ;) We have some apps here at work that look just like native Windows apps that are written in Java. The problem though is that it is slow. It's a lot better than it used to be, but my computer (2.4 GHz Core 2 Duo with 3 GB of RAM) still slows to a crawl when this app starts up. - jasonh
@jasonh: I don't consider Eclipse to have a decent UI because it doesn't particularly jive with any OS but windows. I'd have to see these apps that look just like windows apps... - RCIX
@RCIX: Unfortunately they're proprietary, so I don't have any links. - jasonh
@joachim, the trick Sun uses under Windows to make Java start faster is to have a process keep a copy of the essential JVM files in memory instead of being swapped out to disk. The random access to the JVM jar files makes unswapping much slower than needed. - Thorbjørn Ravn Andersen
@Zan, is this Swing applications or Console applications? - Thorbjørn Ravn Andersen
@Thorbjørn: A Swing app I believe. The specific app I was talking about is GURPS Character Sheet, available here: sourceforge.net/projects/gcs-java - Zan Lynx
@Zan, just tried it. From starting gcs to the open dialogue took 6 seconds for a cold start (never launched before, no running JVM), and 3 seconds for a warm start (immediately relaunching after quiting the previous run). What numbers do you see? - Thorbjørn Ravn Andersen
(1) @Thorbjørn: Sounds about right. But time starting Safari or Pages or Numbers. Much faster. - Zan Lynx
Again with the "early Java implementation" and "JVM startup used to be slow" arguments... Has any of you ever tried restarting Tomcat, or any other Java application server, running on the most modern implementation of Java you can find, and compare it with restarting any other application server written in any other dynamic language? There's just no comparison. - Tobia
2
[+40] [2010-02-02 19:57:10] Sami

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.


(2) agreed, and +1 on the whole post because you present a valid point, however, C++ for example has the different fame of being difficult to debug, and easy to blow your whole leg off, but seldom I heard of C++ being slow as much as I heard about java. - Stefano Borini
3
[+33] [2010-01-29 18:36:07] Jerry Coffin

You seem to be asking two rather different questions:

  1. Is Java really slow, and if so why?
  2. Why is Java perceived as slow, even though it's faster than many alternatives?

The first of these is more or less a "how long is a rope" kind of question. It comes down to your definition of "slow". Compared to a pure interpreter, Java is extremely fast. Compared to other languages that are (normally) compiled to some sort of bytecode, then dynamically compiled to machine code (e.g. C# or anything else on .NET) Java is roughly on a par. Compared to the languages that are normally compiled to pure machine code, and have (often large) teams of people working on nothing but improving their optimizers (e.g. C, C++, Fortran, Ada) Java does pretty well at a few things, but overall tends to be at least somewhat slower.

A lot of this is related primarily to the implementation -- basically, it comes down to the fact that a user is waiting while a dynamic/JIT compiler runs, so unless you have a program that runs for quite a while to start with, it's hard to justify having the compiler spend a lot of time on difficult optimizations. Therefore, most Java (and C#, etc.) compilers don't put a lot of effort into really difficult optimizations. In a lot of cases, it's less about what optimizations are done, than where they're applied. Many optimization problems are NP complete, so the time they take grows quickly with the size of problem being attacked. One way to keep time within reason is to only apply the optimization to something like a single function at a time. When it's only the developer waiting for the compiler, you can afford to take a lot longer, and apply that same optimization to much larger chunks of the program. Likewise, the code for some optimizations is pretty hairy (and therefore can be pretty big). Again, since the user is waiting while that code loads (and the JVM startup time is often a significant factor in the overall time), the implementation has to balance time saved in one place vs. lost in another -- and given how little code benefits from the hairy optimizations, keeping the JVM small is usually more beneficial.

A second problem is that with Java, you frequently get a more or less "one size fits all" kind of solution. Just for example, for many Java developers Swing is essentially the only windowing library available. In something like C++, there are literally dozens of windowing libraries, application frameworks, etc., each with its own set of compromises between ease of use vs. fast execution, consistent look and feel vs. native look and feel, and so on. The only real sticking point is that some (e.g. Qt) can be quite expensive (at least for commercial use).

Third a lot of code written in C++ (and C even more so) is simply older and more mature. At lot of it contains a core of routines written decades ago, when spending extra time optimizing the code was normal, expected behavior. That often has a real benefit in code that's smaller and faster. C++ (or C) gets the credit for the code being small and fast, but it's really much more a product of the developer and the constraints of the time the code was written. To an extent, this leads to a self-fulfilling prophecy -- when people care about speed, they often select C++ because it has that reputation. They put extra time and effort into optimization, and a new generation of fast C++ code is written.

To summarize, the normal implementation of Java makes maximum optimization problematic at best. Worse, where Java is visible, such things as windowing toolkits and JVM startup time often play a larger role than the execution speed of the language itself anyway. In a lot of cases, C and C++ also get credit for what's really the product of simply working harder at optimization.

As to the second question, I think it's largely a matter of human nature at work. A few zealots make rather inflated claims about Java being blindingly fast. Somebody tries it out, and finds that even a trivial program takes a few seconds to get started, and feels slow and clumsy when it does run. Few probably bother analyzing things to realize that a great deal of this is the startup time of the JVM, and the fact that when they first try things out, none of the code has been compiled yet -- some of the code is being interpreted, and some being compiled while they wait. Worse, even when it runs fast enough, the look and feel will usually seem foreign and clumsy to most users, so even if objective measurements showed fast response times, it'd still seem clumsy.

Adding those together leads to a fairly simple and natural reaction: that Java is slow, ugly and clumsy. Given the hype saying it's really fast, there's a tendency to overreact and conclude think of it as horribly slow, instead of a (more accurate) "slightly slower, and that mostly under specific circumstances." This is generally at its worst for a developer writing the first few programs in the language. Execution of a "hello world" program in most languages appears instantaneous, but in Java there's an easily perceptible pause as the JVM starts up. Even a pure interpreter that runs much more slowly on tight loops and such will still often appear faster for code like this, simply because it can get loaded and started executing a bit sooner.


4
[+16] [2010-01-29 16:49:25] Dan Dyer

It's out-dated information from the early days (mid-to-late 1990s) of Java. Every major version of Java has introduced significant speed-ups compared to the previous version. With Oracle apparently merging JRockit with Sun's JVM for Java 7, this trend looks set to continue.

Compared to many other popular modern languages (Python, Ruby, PHP), Java is actually significantly faster for most uses. It doesn't quite match C or C++ but for many tasks it's close enough. The real performance concerns ought to be about how much memory it ends up using.


5
[+14] [2010-01-29 17:39:35] Thomas Pornin

The main culprit in the "long startup time" is dynamic linking. A Java application consists of compiled classes. Each class references other classes (for argument types, method invocations...) by name. The JVM must examine and match those names upon startup. It does so incrementally, doing only the parts that it needs at any given time, but that is still some work to do.

In a C application, that linking phase occurs at the end of the compilation. It is slow, especially for big applications, but only the developer sees it. Linking yields an executable file which the OS simply has to load in RAM "as is".

In Java, linking occurs every single time that the application is run. Hence the long startup time.

Various optimizations have been applied, including caching techniques, and computers get faster (and they get "more faster" than applications get "more bigger"), so the problem importance has much reduced lately; but the old prejudice remains.

As for performance afterwards, my own benchmarks on compact computations with array accesses (mostly hash functions and other cryptographic algorithms) usually show that optimized C code is about 3x faster than Java code; sometimes C is only 30% faster than Java, sometimes C can be 4x faster, depending on the implemented algorithm. I saw a 10x factor when the "C" code was actually assembly for big integer arithmetics, due to the 64x64->128 multiplication opcodes that the processor offers but Java cannot use because its longest integer type is the 64-bit long. This is an edge case. Under practical conditions, I/O and memory bandwidth considerations prevent C code from being really three times faster than Java.


Hmm... I thought most C libraries were dynamically linked nowadays too. Or are you speaking of something different? - Sean McMillan
(4) @Sean: dynamic linking for C occurs for "external symbols": the functions which are used in one DLL and defined in another. A typical C application will use a dozen DLL. For Java dynamic linking occurs for all methods in all classes: there are thousands of those in a typical Java application (including the standard library). In the C world, most of the linking (all links which do not cross a DLL boundary) are resolved at compile time, only a small proportion still remains to do at runtime. - Thomas Pornin
6
[+14] [2010-05-26 09:05:23] Hamaad Shah

Java is definitely slow, especially for quantitative work.

I use a combination of R [1], Python and C/C++ with optimised multithreaded ATLAS [2] libraries. In each of these languages I can matrix multiply a 3000 by 3000 matrix of doubles with itself in around 4 seconds. Using Colt and Parallel Colt in Java, the same operation take 185 seconds! Astonishing despite these java libraries being parallel in nature.

So all in all, pure Java is unsuitable for quantitative work. Jblas seems to be the best linear algebra library for Java as it uses ATLAS.

My machine is an HP Core 2 Duo [3] with 3 GB of RAM. I use 64-bit Ubuntu 10.04 [4] (Lucid Lynx).

[1] http://en.wikipedia.org/wiki/R_%28programming_language%29
[2] http://en.wikipedia.org/wiki/Automatically_Tuned_Linear_Algebra_Software
[3] https://en.wikipedia.org/wiki/Intel_Core#Core_2_Duo
[4] https://en.wikipedia.org/wiki/List_of_Ubuntu_releases#Ubuntu_10.04_LTS_.28Lucid_Lynx.29

Following on from my aforementioned comment, I performed the same matrix multiplication operation using JAMA and it took around 50 seconds. Still too slow compared to other languages. - Hamaad Shah
(7) How long did Java take when you performed the multiplication in the libraires called via JNI. Given that anything you can do in C/C++ you can do with JNI (add a few hundred mnano-seconds) the margin is relatively small. I am guessing your R and Python matrix multiplication wasn't written in R or Python, just called from those languages. - Peter Lawrey
(2) Out of curiosity, have you done any profiling to identify if you have some hotspot in your code (type conversion/autoboxing)? - Thorbjørn Ravn Andersen
7
[+10] [2010-01-29 17:04:41] Spike Williams

For most people's experience interacting with it - Java is slow. We've all seen that coffee cup spinning around on our browser before some applet comes up. It takes a while to spin up the JVM and download the applet binaries, and that impacts the user experience in a way that is noticed.

It doesn't help that the slow JVM spin-up and applet download time is conspicuously branded with a Java coffee cup, so people associate the wait with Java. When Flash [1] takes a long time to load, the branding of the "loading" message is specified by the Flash developer, so people don't blame Flash technology as a whole.

All of this has nothing to do with Java's performance on a server, or in the many other ways that Java gets used outside the browser. But it's what people see, and what non-Java developers remember when they think about Java.

[1] http://en.wikipedia.org/wiki/Adobe_Flash

8
[+9] [2010-01-29 17:26:58] Rex Kerr

Java has the reputation of being slow because it was slow. The first versions of Java had either no or rather poor Just In Time compilation. This meant that the code, although bytecode, was being interpreted, so even for the simplest operations (like adding two integers) the machine had to do all sorts of compares and pointer dereferences and function calls. The JIT compiler has been ever-improving; now it's at the point where if I write C++ code carelessly and Java code carelessly, Java will sometimes outperform C++ because the JIT compiler realizes that I've got some unnecessary pointer dereferencing and will take care of it for me.

If you want to see just how big a difference JIT compilation makes, check out the interpreted vs. non-interpreted benchmarks at the Computer Languages Benchmark Game [1]. (Pidigits uses an external library to do all the computations, so that benchmark doesn't change; the others show a 6-16x speedup!)

So, that's the main reason. There are a variety of other, lesser reasons that did not help matters: originally, Java startup time was slow (now fixed); web apps in Java take a long time to download (much less true now with widely accessible broadband, and with large things like movies being expected); the UI Swing was not (and still is not) written with performance in mind so it is much less snappy than equivalents in e.g. C++.

[1] http://shootout.alioth.debian.org/u64/benchmark.php?test=all&lang=javaxint&lang2=java

9
[+6] [2010-01-29 16:53:39] Kaleb Brasee

Java WAS slow, back in the day. It has become much faster, due to a few generations of performance enhancements [1]. Last I heard, it is usually within 10% of C# speed -- sometimes faster, sometimes slower.

Java applet startup is still slow because you've got to start a whole JVM, which has to load all it's classes. Somewhat like booting another computer. Once the JVM starts it is quite fast, but the startup is usually what people remember.

Also, there are at least a few people [2] that will never believe in the viability of Java.

[1] http://en.wikipedia.org/wiki/Java_performance#Sun_Java_versions_performance_improvements
[2] http://thedailywtf.com/Articles/Java-is-Slow!.aspx

(1) JVM startup is still much slower than CLR startup, unfortunately. This is because Sun has dragged its feet in the worst way in releasing Java 7, so we're stuck with incremental patches to the 4 year old Java 6. - BobMcGee
(3) Wow, Java 6 is 4 years old??? Yep I guess so (if you count the beta). Still feels new to me -- I just stopped using 1.4 at work. - Kaleb Brasee
Java 1.4 is usable, but kind of sucktastic, since 1.5 and 1.6 added a lot of performance boosts and syntactic sugar. Bounds-check and System.arraycopy optimizations were introduced since then. So were a lot of synchronization improvements. I think it's fair to say 1.4 genuinely IS slow. - BobMcGee
LOL, I know -- every time I have to iterate manually or use an array instead of a generic List, I want to break my laptop in half... IBM has actually had Java 5 available on WAS 6.1 for years, but I've been stuck on WAS 6.0 :( I have been using Java 5/6 since it came out for my own stuff, but am just limited by old server versions at work. There are double-digit percent performance improvements from 1.4 to the newest versions for a lot of things, and I am looking forward to them. - Kaleb Brasee
10
[+6] [2010-01-29 17:07:06] Dieter

Stefano:

I have been with Java since the beginning, so from my point of view the fame of being slow was created by non-responsive and slow GUI frontends (AWT, and then Swing) and in Applets probably because of the additional slow startup times of the VM's.

Java has stipulated and promoted a lot of research in the VM area, and there have been quite some improvements, including the garbage collection (you can tune a lot of things actually; however, often I see systems where only defaults are used) and hotspot optimization (which at the beginning and probably still is more efficient on the server side).

Java at the backend and the computational level is not that slow. Colt [1] is one of the best examples:

The latest stable Colt release breaks the 1.9 Gflop/s barrier on JDK ibm-1.4.1, RedHat 9.0, 2x IntelXeon@2.8 GHz.

There are many things outside mainstream Java that should be considered, like Realtime Java or special mechanisms to enhance the speed like Javolution [2], as well as Ahead-Of-Time compilation (like gcj). Also, there are IC's that can execute Java Bytecode directly, like for example the one that is in the current iPhones and iPods ARM Jazelle [3].

I think that generally today it's a political decision (like no Java support on the iPhone/iPod), and a decision against Java as a language (because many think it is too verbose).

However, there are many other languages for the Java VM nowadays (e.g. Python, Ruby, JavaScript, Groovy, Scala etc.) which may be an alternative.

Personally I continue to enjoy it as a flexible and reliable platform, with excellent tooling and library availability, that allows one to work with everything from the smallest device (e.g. JavaCard) to the largest servers.

[1] http://acs.lbl.gov/~hoschek/colt/
[2] http://javolution.org/
[3] http://www.arm.com/products/multimedia/java/jazelle.html

Ok, so another bad reputation came from the GUI toolkit. Of course I assume that, since modern JVM use native widgets, they hook into the OS libraries, right? or do they use AWT/Swing to render the same look and feel of the host platform ? - Stefano Borini
Stefano: Swing is actually based on the idea of non-native universal rendering of widgets, so your assumption is kind of wrong. It is indeed a "pluggable look & feel" mechanism that allows Swing components to emulate the appearance of native components. If you are looking for something like that, you may want to check out SWT (eclipse.org/swt), that will indeed hook into the native OS and use native widgets using JNI (which is said to be a bottleneck). - Dieter
Java2D (used for Swing) is very quick these days, and using native widgets (SWT) provides no performance benefit. At least, that's what I read when I was deciding whether to learn Swing or SWT 6 months ago. - Luigi a.k.a. Rhys
11
[+4] [2010-01-29 17:11:45] mobiGeek

A hammer is much slower at rolling out dough than many other tools. Doesn't make the hammer "slower", nor less useful for the tasks that it is designed to do.

As a general programming language, Java is on par with many (if not most) for a wide array of programming tasks. There are specific, trivial tests for which Java will not outperform hand-coded solutions in less sophisticated languages, ones that are "closer to the metal".

But when it comes to "real world applications", Java often is the Right Tool. Now, that said, nothing will stop developers from making a slow-performing solution using ANY tool. Misuse of tool is a well known problem (just look at PHP's and VB's reputations). However, Java's (mostly) clean design and syntax does do a lot to reduce misuse.


12
[+3] [2010-01-29 16:48:04] Pascal Cuoq

Java is a high-level language and its reputation nowadays is to have performance on par with other, comparable high-level languages.

  1. It has dynamic binding [1] semantics. Compared to C++ where non-virtual methods are compiled as function calls, even the best Java compiler in the world has to produce code that is less efficient. But it's also a cleaner, more high-level semantic.

  2. I do not remember the details, but I heard in the early days of Java that there was a mutex per Java object, to be acquired and released by each method. That tends to make it better adapted to concurrency, although unfortunately just a mutex per object will not protect you from races or deadlocks or any of the bad things that can happen in concurrent programs. That part, if true, is a little naive, but it came from good intentions. Feel free to fill me in on the details if you know more about this aspect.

  3. Another way in which Java is a high-level language is by having Garbage-Collection [2]. Garbage-Collection may be slower than malloc and free for programs that allocate at once all the memory they need and work with that. The problem is, in languages that do not have Garbage-Collection, programmers tend to write only programs that allocate all the memory they need at once and fail if it turns out some arbitrary maximum size constant has been overflown. So the comparison is apples to oranges. When programmers make the effort to write and debug programs with dynamic allocation of chained structures in non-GC languages, they sometimes find that their programs are no longer faster than in a GC language, because malloc and free are not free! They have overhead too... Plus, not having a GC forces to specify who frees what, and having to specify who frees what in turn sometime forces you to make copies — when several functions are going to need the data and it's not clear which will be using it last — whereas copying wouldn't have been necessary in a GC language.

[1] http://en.wikipedia.org/wiki/Dynamic_binding_(computer_science)
[2] http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)

1. Probably not true with HotSpot. 2. Only if you mark the method as synchronized. - Winston Ewert
(1) 1. The compiler doesn't optimise the code, but the JVM is smart enough to dynamically determine only one or two virtual methods are typically called and can call them staticly or even inline them. I am pretty sure C++ cannot inline virtual methods. 2. Every Java Object has a lock. It has a small overhead (about a byte) on each object but has little impact if not used. 3. In Java you can allocate at once all the Objects you need. This can give you can application which does not GC all day. ;) Java's GC is implicitly multi-threaded, something which requires special libraires in C++. - Peter Lawrey
C++ can inline virtual calls, but Java can do it in more cases, and is also stronger with optimising megamorphic call sites. - Piotr Kołaczkowski
13
[+2] [2010-01-29 16:52:06] Ken Liu

In the mid-nineties when Java hit the mainstream, C++ was the dominant language, and the web was still fairly new. Also, JVMs and GC were relatively new concepts in mainstream development. The early JVMs were kind of slow (compared to C++ running on bare metal) and also suffered from sometimes long garbage collection pauses, which led to a reputation of Java being slow.


was this due to the technology behind the GC ? I know they have some strategies (like generational layers for objects) to be more efficient in the GC phase. What was the strategy at that time ? - Stefano Borini
(1) IANA JVM expert, but I think at the time there was a single threaded mark/sweep algorithm used for GC, which required the whole JVM to pause while the GC was being performed. Nowadays there is concurrent mark/sweep and also there are other many other performance enhancements in the JVM. - Ken Liu
(2) Modern GC algorithms are nice but I think that the biggest improvement was JIT. - Pascal Thivent
14
[+1] [2010-01-29 16:52:09] caskey

As Pascal says, Java is on par with other high-level languages. However, as someone who worked with the original JVMs on Windows 98 [1], at the time the level of abstraction provided by the Java virtual machine was, shall we say, painful.

Basically, it was software emulation with little or no optimization that we take for granted today in the JVM.

[1] https://en.wikipedia.org/wiki/Windows_98

15
[+1] [2010-02-01 16:18:36] Wojciech Kaczmarek

Many Java desktop apps (these times: things like Eclipse) have bad GUI responsiveness, probably due to the high memory consumption and the fact that classloader can do lots of IO. It's improving but was worse few years ago.

Many (most) people like to do generalizations so they say "Java is slow" because they perceive the apps are slow when they interact with them.


do you think the high memory consumption comes from the tool or from the java libraries ? - Stefano Borini
In the case of Eclipse - from the Eclipse infrastructure itself. Same for "heavy" GUIs in the past (JBuilder as I remember it). I have a gut feeling that it's because lots of boilerplate objects are needed to use a plugin architecture (like Eclipse) in a statically typed language. Emacs has plugins as well and its memory consumption is 10-20x less than Eclipse when doing typical coding. Emacs Lisp code is compiled to bytecode and loaded into emacs instance, then run - similar to Java classloader. I guess in Java there are tons of intermediate objects instantiated to allow some plugability. - Wojciech Kaczmarek
16
[+1] [2010-02-18 23:39:17] Thorbjørn Ravn Andersen

The major problem with java applications is that it is huge due to the large size of the stock runtime library. Huge programs fill a lot in memory and tend to swap, meaning they become slow.

The reason the Sun JVM is large is because it has a very good byte code interpreter which works by keeping track of a lot of things. That means much data, which means memory.

You may want to look at the jamvm virtual machine which is an reasonably fast interpreter (no native code) and very small. It even starts up fast.


17
[0] [2010-01-29 17:01:45] Mr. Boy

People normally trot out the "it's interpreted" line. Because once upon a time, it was, and bad press gets handed down by people who dumped Java as 'too slow' and never returned to test newer versions.

Or perhaps "people are idiots" is a better answer.


18
[0] [2010-01-29 17:54:17] helpermethod

I think some day, maybe not in the too-near future, JIT-compiled languages will outperform compiled languages in any aspect (well, maybe not startup time/memory consumption) due to the fact that JIT-compilers can make heavy use of runtime behaviour and the platform they're running on.


(6) I think what you mean to say is that JIT-compiled (not interpreted) code will beat AoT code. Interpretation will always be slower than running compiled code. This is why JIT compilers are used. The catch: there is little difference between an ahead of time compiler and a JIT compiler in terms of output, except that a JIT compiler must compile more quickly, and can use runtime info to hint its optimizations. Platform-specific AoT compilers with platform-specific optimizations will almost always beat JIT because there is no limit how much time they spend on optimization. - BobMcGee
Thanks for the answer, never thought about the little time JIT compilers have at their disposal. - helpermethod
you mean, something like hotspot adaptive optimization ? - Stefano Borini
(2) @BobMcGee: Very right. A C++ program can be built to run slowly with profile feedback for all its operations. Then the compiler is free to rebuild a very fast version using a half-hour of CPU time and 2 GB of RAM. A JIT that did this would make the users leave. - Zan Lynx
+1 @BobMcGee I like your answer and it helps clarify the costs of doing something at runtime vs. compile time. I see a lot of people touting that jit allows the ability to make better optimizations at runtime, but at what cost? that is the question. - bjackfly
(1) JIT compile time is negligible for long running apps like servers. AOT with PGO is more limited compared to JIT for at least 2 reasons. First, most performance difference is achieved by lightweight optimisations. Compare gcc -O2 to gcc -O3. Most of the time there is no difference, sometimes -O3 can be slightly better, sometimes slightly worse, but I never experienced a >2x difference from this. Second, using AOT even with PGO you can only guess what the profile will be at the use-site. Guess wrong, and you're far behind the JIT. And the actual profile can be extremely config-dependent. - Piotr Kołaczkowski
19