This site uses cookies to deliver our services and to show you relevant ads and job listings.
By using our site, you acknowledge that you have read and understand our Cookie Policy, Privacy Policy, and our Terms of Service.
Your use of Stack Overflow’s Products and Services, including the Stack Overflow Network, is subject to these policies and terms.

Join us in building a kind, collaborative learning community via our updated
Code of Conduct.

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.

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site, so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. More info: help center.

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 BoriniJan 30 '10 at 0:35

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.
– BobTurboSep 10 '11 at 4:08

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 ReppenApr 4 '12 at 20:53

19 Answers
19

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.

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.
– SjoerdAug 20 '11 at 12:15

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 KerrSep 30 '11 at 15:14

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.
– SjoerdOct 4 '11 at 13:28

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!
– SjoerdOct 5 '11 at 12:46

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 KerrOct 5 '11 at 17:18

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.

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.
– ChadNCJan 29 '10 at 17:01

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 LynxJan 29 '10 at 17:10

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 - tacklineJan 29 '10 at 18:31

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 SauerFeb 1 '10 at 16:22

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.
– RCIXFeb 2 '10 at 8:26

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.

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 BoriniFeb 3 '10 at 2:20

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.

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.

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 McMillanJun 10 '11 at 21:35

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 PorninJun 10 '11 at 21:42

I use a combination of R, Python and C/C++ with optimised multithreaded ATLAS 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.

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 ShahMay 26 '10 at 11:10

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 LawreyMay 14 '11 at 9:15

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 AndersenFeb 15 '12 at 22:29

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

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. (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++.

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.

LOL, I've had people tell me that C# is 10 times faster than Java.
– Kaleb BraseeJan 29 '10 at 17:08

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.
– BobMcGeeJan 29 '10 at 17:20

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 BraseeJan 29 '10 at 18:04

@Kaleb Let me guess: you are working in an IBM environment >:)
– Pascal ThiventJan 29 '10 at 18:39

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 is one of the best examples:

There are many things outside mainstream Java that should be considered, like Realtime Java or special mechanisms to enhance the speed like Javolution, 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.

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.

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 BoriniJan 29 '10 at 17:16

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).
– DieterJan 29 '10 at 17:55

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 PlingeOct 17 '11 at 23:45

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.

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

It has dynamic binding 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.

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.

Another way in which Java is a high-level language is by having Garbage-Collection. 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. Probably not true with HotSpot. 2. Only if you mark the method as synchronized.
– Winston EwertSep 13 '10 at 16:59

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 LawreyMay 14 '11 at 9:25

C++ can inline virtual calls, but Java can do it in more cases, and is also stronger with optimising megamorphic call sites.
– Piotr KołaczkowskiMay 6 '15 at 8:27

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 BoriniJan 29 '10 at 16:56

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 LiuJan 29 '10 at 17:03

2

Modern GC algorithms are nice but I think that the biggest improvement was JIT.
– Pascal ThiventJan 29 '10 at 17:33

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 BoriniFeb 1 '10 at 17:09

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 KaczmarekFeb 2 '10 at 20:27

As Pascal says, Java is on par with other high-level languages. However, as someone who worked with the original JVMs on Windows 98, 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.

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.

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.

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.
– BobMcGeeJan 30 '10 at 19:00

Thanks for the answer, never thought about the little time JIT compilers have at their disposal.
– helpermethodJan 31 '10 at 11:36

@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 LynxJul 15 '11 at 22:50

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łaczkowskiMay 6 '15 at 8:38

Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).