Jeff's Java wiki FAQ

K.I.L.E.R

Retarded moron
Veteran
http://wiki.java.net/bin/view/Games/JeffFAQ

Why does John Carmack say Java is too slow?

John Carmack is a very intelligent man and he knows his areas, graphics hardware and software and bit-twiddled C coding, extremely well. Like many men who are experts in their own fields however he sometimes falls prey to the mistake of not knowing what he doesn't know.
Mr. Carmack is actually fairly ignorant when it comes to Java technology. His only recent experience with Java has been with the aforementioned cell phones and, like many who come to Java through the phones, he doesn't seem to understand yet that he is dealing with the most limited form of Java there is. His comments are fudementally accurate except that when he says "Java" he really means J2ME/CLDC.
Unfortunateley, since he hasn't explored modern desktop Java at all, he is somewhat blind to where the cell phones are heading.
I suggest all of you read the entire FAQ.
Judging by what others have said in the past, there is mass ignorance when it comes to Java.
I believe there are only 2 people on these boards that have demonstrated some basic knowledge when it comes to Java.
 
OK, tried to read it, and still feel I didn't learn a whole lot new.

I was unable to see just WHY late binding is desirable to early binding - just what does it allow you to do that cannot be achieved efficiently in C/C++ with dlopen() and a branch predictor??

Is Java faster than C/C++ on computational code? This one says a resounding YES and this one says NO; both are backed by dozens of benchmarks - the latter one is quite harshly arguing (with real examples) that 'java-faster-than-C/C++' benchmarks usually suffer from having highly optimized Java code compared against intentionally de-optimized C/C++ code.

Besides, the main gripes people have with Java performance is not usually computational efficiency but rather user interface response slowness and lack of real-time performance guarantees (eg for sound you may want to design around a target latency of ~10 ms; a garbage collector that cannot be coerced to stay below that level would then give you no end of headaches.)
 
arjan de lumens said:
OK, tried to read it, and still feel I didn't learn a whole lot new.

I was unable to see just WHY late binding is desirable to early binding - just what does it allow you to do that cannot be achieved efficiently in C/C++ with dlopen() and a branch predictor??

C++ compilers can't easily convert polymorphic calls to monomorphic calls based on runtime state and dynamically loaded classes. They also can't perform data flow analysis across dynamic dispatch boundaries without profile data feedback.

Sure, you could dlopen() a shared library, but none of the calls made to functions in the library are going to be inlined. The branch predictor can only help save the cost of a dynamic branch/dispatch, but it can't overcome the full deficit the generated code has by not being able to inline calls, and not be able to perform optimizations across dispatch boundaries, just as copy propagation, register elimination, redundancy elimination, etc.

I once compared Java code calling a third party JAR to C++ code calling a dynamic COM controls, and the Java code was much much faster. This is one of the few pathological cases where Java will whip C++. If you've virtual calls that you can't eliminate, and those virtual calls are hotspots in your code, you'll find that J2SE Server VM will generate more efficient x86 code than the C++ compiler, and it's runtime will be faster.

As for predictable GC. You can download an RTSJ implementation if you want. It provides realtime threads, realtime GC with guarantees, multiple heaps -- including a heap with NO GC that you manage yourself, and direct memory access.

The perception that Java is slow is due to two problems: slow startup from cold start (nothing cached in filesystem cache of OS), and a GUI with a lag, due to the architecture of the way events are processed and redraws occur. These are being fixed in upcoming VMs.
 
DemoCoder said:
C++ compilers can't easily convert polymorphic calls to monomorphic calls based on runtime state and dynamically loaded classes. They also can't perform data flow analysis across dynamic dispatch boundaries without profile data feedback.

Sure, you could dlopen() a shared library, but none of the calls made to functions in the library are going to be inlined. The branch predictor can only help save the cost of a dynamic branch/dispatch, but it can't overcome the full deficit the generated code has by not being able to inline calls, and not be able to perform optimizations across dispatch boundaries, just as copy propagation, register elimination, redundancy elimination, etc.

I once compared Java code calling a third party JAR to C++ code calling a dynamic COM controls, and the Java code was much much faster. This is one of the few pathological cases where Java will whip C++. If you've virtual calls that you can't eliminate, and those virtual calls are hotspots in your code, you'll find that J2SE Server VM will generate more efficient x86 code than the C++ compiler, and it's runtime will be faster.
Fair enough. While dynamic dispatch hardly is any slower than static dispatch in itself (at least not on my Athlon64), it does block inlining opportunities, as you rightly point out. Then again, if your performance is limited by the rate at which you can pass through dynamic dispatch, your algorithm (or the code you are interfacing with) is either seriously suboptimal or not really amenable to optimization in the first place.
As for predictable GC. You can download an RTSJ implementation if you want. It provides realtime threads, realtime GC with guarantees, multiple heaps -- including a heap with NO GC that you manage yourself, and direct memory access.
Seems to solve the GC issue rather nicely, from what I could find. Can it avoid JIT delays too?
The perception that Java is slow is due to two problems: slow startup from cold start (nothing cached in filesystem cache of OS), and a GUI with a lag, due to the architecture of the way events are processed and redraws occur. These are being fixed in upcoming VMs.
Fair enough; we have only been waiting for 9 years, we can wait some more.
 
K.I.L.E.R said:
I suggest all of you read the entire FAQ.
Judging by what others have said in the past, there is mass ignorance when it comes to Java.
I believe there are only 2 people on these boards that have demonstrated some basic knowledge when it comes to Java.
From my POV its quite the opposite. At university the CS-Branch basically uses nothing but Java, resulting in Students lacking deeper knowledge of what`s actually happening in the background.
Java is nice for prototyping and guis, but appart from that it uses way to much memory, the only way to reuse code is with deep-inheritance, which is horrible if its the only way doing it. You`ll end up writing interfaces and implementing the same methods a dozend times, because its the only sane way once a project reached a certain size.

Now you got those people knowing only Java, then trying to run the same code on C++ and claiming its not faster. Well, big surprise. The advantage of C++ is, that it can resolve inheritance during compiling, aslong as you dont use virtual methods, and it can take alot more time on spitting out native code than JITs. Using C++-generics will lead a substancial performance-advantage over Classes.
Not using virtual methods might turn up to be a problem in many cases, but if your programm is standalone binary (Games are), there arent many cases you depend on them. In the end, its Java that still got to proove it aint slow, not the other way round. No amount of talking will chanfe that
 
Java is nice for prototyping and guis, but appart from that it uses way to much memory, the only way to reuse code is with deep-inheritance, which is horrible if its the only way doing it.

Out of 100 class files in one of my projects I've only used basic inheritence twice on maybe 10 or so classes.
For code re-usability I've found inheritence to naturally work in very few areas, while the rest I find better ways of doing it.


Where I am, we use Java optionally in my subjects and C/C++ in other subjects. I've used C++ far more than Java throughout my learning years. I could go on about how Java is better and so forth but I wont.
People will pick their language based on their experiences.
I find it no problem to use any language. I'm comfortable with all I've used.
I handed in my computer graphics assignment and it was quite big in the end, it was done in C++. The teacher loved my code. :)

Java is only a requirement in a few classes, which are mainly only about Java.

Now you got those people knowing only Java

Myth. Most people know nothing about Java and that is the problem.
Out of all my friends only 1 knows a bit about Java. They all learn Java mind you, it's just that they don't understand Java.

They get shown how to program but if you take a look at their code you will see an abuse of threads, inheritence which leads to a shoddy design and sub-par performance.

aslong as you dont use virtual methods

That's a bit of an issue with me so I guess I'd better stick to Java because it's better eh? ;)

Using C++-generics will lead a substancial performance-advantage over Classes.
Depends on where the performance limitations are in your code.

No amount of talking will chanfe that

Read Jeff's FAQ. :)
No amount of mis-information will change the fact that Java is a good tool for developers.

If Tim Sweeney or JC came out and stated Java is better than C/C++ I'm sure the attitudes of many will change instantly.
 
K.I.L.E.R said:
Out of 100 class files in one of my projects I've only used basic inheritence twice on maybe 10 or so classes.
For code re-usability I've found inheritence to naturally work in very few areas, while the rest I find better ways of doing it.
its either inheritance or delegation in Java. You get multiple-inheritance for C++, which is very nice if your classes dont fit a single hierarchy tree. I often had 3 or more levels of hierarchie with my Java-Stuff( and I dont even count the everything-is-an-object-nonsense), on C++ I do seperate components and stuff them together as needed, with the compiler doing copy-constructors and similar things for free. Wouldve helped my lots back then.

K.I.L.E.R said:
Where I am, we use Java optionally in my subjects and C/C++ in other subjects. I've used C++ far more than Java throughout my learning years. I could go on about how Java is better and so forth but I wont.
People will pick their language based on their experiences.
I find it no problem to use any language. I'm comfortable with all I've used.
I handed in my computer graphics assignment and it was quite big in the end, it was done in C++. The teacher loved my code. :)

Java is only a requirement in a few classes, which are mainly only about Java.
I can tell you its different out here, I end up helping a cousin alot of Java-stuff. Java has its merits (just try to find a good, useable C++-IDE for Linux or a good free one for Windows, Eclipse dwarfs all those), just I dont think it fits everywhere. I would not start coding a Game in Java, and I would not do it for most Apps as well (non-Webapplications).

K.I.L.E.R said:
Myth. Most people know nothing about Java and that is the problem.
Out of all my friends only 1 knows a bit about Java. They all learn Java mind you, it's just that they don't understand Java.

They get shown how to program but if you take a look at their code you will see an abuse of threads, inheritence which leads to a shoddy design and sub-par performance.
You think they`d to better with C++ ?

K.I.L.E.R said:
That's a bit of an issue with me so I guess I'd better stick to Java because it's better eh? ;)
You can still use it, my point was that Java-centric people use it extensively, even if its not required at all. Is you only need a single virtual method of a C++-Class, its better to just pass a functionpointer - else every function will have the "virtual"-overhead.

K.I.L.E.R said:
Read Jeff's FAQ. :)
No amount of mis-information will change the fact that Java is a good tool for developers.

If Tim Sweeney or JC came out and stated Java is better than C/C++ I'm sure the attitudes of many will change instantly.
If there`d be a kickass-game been written in Java the attitudes would change. But guess that wont happen.
 
Npl said:
From my POV its quite the opposite. At university the CS-Branch basically uses nothing but Java, resulting in Students lacking deeper knowledge of what`s actually happening in the background.

This has nothing to do with Java specifically, but with your university. Historically, top CS universities taught many courses with LISP. Any university that teaches CS should teach "what happens in the background" regardless of what the implementation language is. For example, with LISP, this would usually entail building a LISP interpreter or compiler with LISP itself, as well as building a machine language simulator in LISP.

If the university wants to teach what "happens at the low level", it should offer computer architecture, assembly, and compiler development courses. But teaching all the CS courses in C or other low level language just gets in the way of what's important. What CS is trying to teach is algorithms, not high performance optimization of real time programming.


Java is nice for prototyping and guis, but appart from that it uses way to much memory, the only way to reuse code is with deep-inheritance, which is horrible if its the only way doing it. You`ll end up writing interfaces and implementing the same methods a dozend times, because its the only sane way once a project reached a certain size.

More FUD. I've worked on many *HUGE* Java projects that neither require deep-inheritance nor reimplementation of interfaces. Both are usually symptoms of poor design, especially from former C++ programmers who decided to learn Java quick. Each language has their own idioms. C++ templates on any non-trivial project size also have their issues, especially when one needs to track down bugs in template libraries written by third party teams. The correct answer is proper design.

Most programs simply don't need mixins, and those that do can be handled by clever use of reflection and/or annotations if you don't want delegation.

As for memory usage, it's completely determined by how much RAM you want to give the VM. Simply looking at the process space taken is misleading. I've run servlet containers with as little as 16mb of heap.


Now you got those people knowing only Java, then trying to run the same code on C++ and claiming its not faster. Well, big surprise. The advantage of C++ is, that it can resolve inheritance during compiling, aslong as you dont use virtual methods, and it can take alot more time on spitting out native code than JITs. Using C++-generics will lead a substancial performance-advantage over Classes.

Virtual methods are not really the issue being discussed, but the more general problem of dealing with late binding. In today's world, one can't statically link or early bind against all application code, because one depends on many third party or operating system components that reside in shared objects. Large software projects make liberal use of third party components and one can almost never compile under a "closed world" assumption, except in limited circumstances like game consoles.

In C/C++ if you use DLLs, you pay a much more expensive penalty than the Java equivalent. Not just interms of indirection, but a loss of a large number of possible optimizations, was well as poor memory locality.

Not using virtual methods might turn up to be a problem in many cases, but if your programm is standalone binary (Games are), there arent many cases you depend on them. In the end, its Java that still got to proove it aint slow, not the other way round. No amount of talking will chanfe that

Java has proven it's not slow. All one needs to do is look at LINPACK. No one's arguing it's going to be the best game developers language or best OS development language.. But for many program domains, for example, enterprise applications, it crushes C++ in programmable productivity (as does LISP, and most dynamic languages). C++'s language "features" are simply not needed for many classes of applications.

C++ IMHO is a very poorly designed language. Java's not the best. I'd take OCaml, LISP/Scheme, Clean, over it any day. C++'s metaprogramming is a joke compared to macros in Scheme. Java sadly has none, but makes up for it somewhat with annotations and APT in 1.5
 
Last edited by a moderator:
You've also been reading the Java.net articles?
I find they give me some damn good ideas on how to accomplish things.

Most programs simply don't need mixins, and those that do can be handled by clever use of reflection and/or annotations if you don't want delegation.
 
No, just experience. I find that in the vast majority of cases where one actually wants code reuse, one starts off with a specific implementation, and then on one generalizes it. It's simply not a case of inheritance, delegation, or using generics, but also one of refactoring. Except for trivial reusability (map/filter/reduce, search, sort, visitor, etc) to reuse code that provides specific functionality often entails more than parameterizing it via parametric polymorphism.

In Java, with good IDEs like IntelliJ or Eclipse, one usablly refactors code into a utility class. However, if one wishes, one can use reflection, runtime or compile time annotations to achieve meta programming.

For example, implementing JMX Dynamic MBeans is a pain, so I wrote a set of annotations to mark classes, methods, properies, and parameters with JMX specific attributes. Then, a runtime interceptor simply injects the needed MBean implementation onto any class that has been annotated. Hibernate 3.0 works the same way as does XML schema mappers like JAXB2.0. It's a limited form of aspect oriented programming.
 
Annotations can also be kinda of used as generic programming.
Create an annotation interface, mark those classes with that annotation and when you send them down into a utility class to handle them you will do so generically.

It's impossible to tell what's the best way of doing something, so I go with what's naturally the best for my set of requirements.
I try not to abstract things too much, even though I do tend to get carried away with it sometimes.

When it comes to writing games in Java I tend to avoid RTTI, however I find in many cases that RTTI(even though considered slow) isn't an actual performance issue in my code when used properly.
I should take advantages of JBeans instead writing my own JB like framework.

I use Eclipse, I can't really use any other IDE because they either cost money(Intelli J IDEA, I'm not developing professional apps just hobby stuff) or Netbeans(Not as many features as Eclipse).
Eclipse is VERY powerful. If I switch to Netbeans I'd have to learn all the shortcuts again and stuff like that. :/

Jeff has updated the FAQ after reading the comments in this thread:
Why is Java a late bound language?

This is an interesting question and one that properly should be answered by the original designers of the Java(tm) Platform, but I'll give you my perceptions.
Java is designed to be a highly modular language. This allows for very clean seperation of logical units of code. It is worth noting that the inspiration for Java came equally from C++ and from Modula2/Modula3. As I understand it, it was the perception of the original language designers that the more modular a language is, the more re-usable code becomes and the less re-inventing the wheel that needs to be done when starting a new project.
My own experience has certainly backed that up. As a C programmer of 15 years and a C++ programmer of 10 years, I have personally always strived towards more modular and reusable code. In the end however the early-bound nature of languages like C and C++ have always pushed me away from building a truely reusable code base. (The formal observation of why this happens in C++ is summed up in the "fragile base class" explaination.) In Java, I have a utils package I have been growing over the years and I very seldom need to re-write anything I've put into it.
While modularity is possible in C through DLLs, the interface to DLLs is limited to a fixed call interafce and does not have the flexability of a Java class library where I can either instantiate the objects as is, or import and modify them through inheritance. While in theory you can do almost anything you can do with inheritance through function pointers in C, in practice you have to think much further ahead and build specific infrastructure into your DLL code to allow for this.
As important, because modularity is central to Java, it is fast in Java. As explained above the VM is tuned to deal with such late bound code as a primary purpose. C DLLs by definition cannot be inlined or oherwise take part in global optimization. The same is true for the late-binding mechanism in C++ -- virtual method calls.
For all these reasons, I find Java late binding a vast improvement over the previous primarily early bound languages.
Special thanks goes to the Beyond3D.com community for pointing out the need for the above point.
 
KDE which uses KDE/Qt/C++ stack, suffers likely more than any other desktop environment from the issues Demo has pointed out.

KDE and KDE apps in general use an intense amount of shared components, largely due to KParts and KIO_Slaves. Currently, there is a work going on in reducing symbol visibility for instance, this dramatically reduces the amount of time for startup and even program execution. Even then, things only improve so much because there is no optimisation across the various libraries.

There is some work going on with getting LLVM into the tool chain which besides moving bindings into the compiler tool chain, might allow for some runtime profile based optimisations.
 
I agree with Demo. Most often, people won't first spend time writing generic interfaces and classes, and slowly put those together to create the functional ones, but just build a class that works directly. And when they need one alike, they'll inherit from that one, declaring the methods they want to override as virtual in the first class. That's bad. And not why we have things like interfaces and virtual methods in the first place.
 
Back
Top