Skip to main content
GameDev.net gamedev.net
🔒 Locked

I guess I owe Java an apology

Started by Harry Hunt May 28, 2008 at 5:33 PM 35 replies 8k views
Original Post
Harry Hunt
Harry Hunt
...well, maybe not an apology. So I always thought Java was a useful but boring programming language (I still think it is) and I figured that because most Java VMs have at least some form of a "stop the world" gargabe collector, it wasn't the best choice for developing games in. In fact, I've written a simple space shoot-em-up in Java, and it would lag noticably whenever the garbage collector kicked in. Of course that was back in the day and not only have the garbage collectors in most Java VMs improved significantly since then, we also have multi-core now. So does concurrent generational garbage collection + a multi-core CPU equal no lags? Apparently it does. I played Jake today which is a Java port of Quake 2 and it ran extremely well with no lags whatsoever. To make sure that it wasn't just the game using some mean object pooling scheme, I ran it on a single-core for comparison and it lagged noticably. So there you have it, Java + multi-core + game programming = a match made in heaven. Well maybe not in heaven, but you get the idea. Since we're inevitably on a road towards many-core, I think it's only a matter of time until managed languages will at least to a large extent replace C++ as the programming language of choice for game development. If we're to have 80 cores at our disposable soon, we might as well use one of those to clean up our garbage. And before you get the wrong idea: I have absolutely nothing against C++ or Java. Just phantasizing about the future, that's all.
fpsgamer
fpsgamer
I played Jake a while back and felt exactly the same way. But something still confused me: Even though the game runs beautifully on new CPUs, I did notice that the game seriously falters on CPUs of a certain age -- CPUs that would be able to run the Original 'C' version of Quake no problem. That seriously made me wonder why that was.

I am by no means an expert in Java, Compilers etc, so I would seriously appreciate a breakdown of why Java has so many clearly perceived performance issues. Does it strictly have to do with the JVM implementations or is it something inherent in the language spec that has a negative effect on runtime performance? Shouldn't the JIT compiler theoretically produce byte code as efficient as any other compiler?
Koobazaur
Koobazaur
Don't forget you were running Quake 2. A game that is over 10 years old. And you need a dual core to run it on Java. Doesn't that make you think a little?

Managed languages will definitely keep on improving, but they will not reach the efficiency on non-manged ones, at least not in current state. While JIT can produce bytecode as effective as unmanged, there's still other overhead, the most notable being, obviously, the garbage collector. A GC, while more conviniet, will always be less efficient than good memory management in first place ala C/C++. And sure, you can spare the extra few CPU cycles on a GC when running a ten year old game, but try that with the latest, such as Crysis, and those few extra CPU cycles become a big price to pay.

In modern games (not all of them, of course) performance is usually number one factor. Managed languages will always be behind unamanged in performance - they can get close, but they wont be as efficient by very definition. Many small indie devs working on not-the-top-of-the-line games can sure benefit from them, but I don't see any of the blockbuster, resource hogging and performance bending game devs switching any time soon, if ever.
Comrade, Listen! The Glorious Commonwealth's first Airship has been compromised! Who is the saboteur? Who can be saved? Uncover what the passengers are hiding and write the grisly conclusion of its final hours in an open-ended, player-driven adventure. Dziekujemy! -- Karaski: What Goes Up...
outRider
outRider
Quote:
Original post by fpsgamer
Shouldn't the JIT compiler theoretically produce byte code as efficient as any other compiler?


Theoretically, yes, if it had all the time and memory in the world. Practically, no; they typically produce inferior code because they have to make trade-offs.
Metorical
Metorical
This might be obvious to some but not others... there's a lot you can do with the garbage collector to change how it works!

Unfortunately I'm not an expert on the subject as I only really came across it when configuring memory usage for some hungry apps that could eat up to 16GiB of RAM *nom nom nom* I didn't need to delve in to but perhaps someone else has, any experts here?

I don't think there's a lot of Java users on GDNET though.
Metorical
Metorical
Oh and I remember playing Quake 3 in a java app loaded over a web page... anyone remember what that was called?

Edit: also see http://www.gamasutra.com/view/feature/3347/dirty_java_using_the_java_native_.php
nilkn
nilkn
Quote:
Original post by Koobazaur
And sure, you can spare the extra few CPU cycles on a GC when running a ten year old game, but try that with the latest, such as Crysis, and those few extra CPU cycles become a big price to pay.


For the sake of argument, assume your point here. Even then other forces may yield the same result anticipated in the OP:

Crysis actually sold fairly poorly, and I believe a major reason for this is because the game was simply too demanding. Gaming is becoming an increasingly expensive hobby, and the rapid development of advanced graphical techniques has contributed to the commercial failure of a lot of otherwise phenomenal games like Crysis simply because too few people could run them properly.

I'd like to believe that this will continue, pushing the game industry back from overloading top-notch games with too many performance-intensive tricks, which will reduce significantly the need for unmanaged languages and, as a logical complement, increase the viability of using managed languages for large-scale, triple-A projects.

This is all said taking your point as a premise, but I believe that it is highly disputable that managed languages are actually less efficient than their unmanaged counterparts.

[Edited by - nilkn on May 28, 2008 10:21:19 PM]
daviangel
daviangel
Yeah I just read a blog post directly related to this you'd probably be intrested in then:

"So actually, this is funny, because, all right, show of hands here. We've all heard this for fifteen years now – is it true? Is Java as fast as C++? Who says yes? All right... we've got a small number of hands... so I assume the rest of you are like, don't know, or it doesn't matter, or "No."

[Audience member: "We read your slides."] You read my slides. OK. I don't know... I can't remember what I put in my slides.

But it's interesting because C++ is obviously faster for, you know, the short-running [programs], but Java cheated very recently. With multicore! This is actually becoming a huge thorn in the side of all the C++ programmers, including my colleagues at Google, who've written vast amounts of C++ code that doesn't take advantage of multicore. And so the extent to which the cores, you know, the processors become parallel, C++ is gonna fall behind.

Now obviously threads don't scale that well either, right? So the Java people have got a leg up for a while, because you can use ten threads or a hundred threads, but you're not going to use a million threads! It's not going to be Erlang on you all of the sudden. So obviously a better concurrency option – and that's a huge rat's nest that I'm not going to go into right now – but it's gonna be the right way to go.

But for now, Java programs are getting amazing throughput because they can parallelize and they can take advantage of it. They cheated! Right? But threads aside, the JVM has gotten really really fast, and at Google it's now widely admitted on the Java side that Java's just as fast as C++. [(laughter)]
"

I also just watched a video with Stroustroup the creator of C++ and he kept talking about how the next version would include stuff to make multicore programming easier so it seems they are aware of this.
So it seems everyone is jumping on the multicore bandwagon now with dualcore cpu's being dirtcheap and becoming the norm now. Intel is pushing Threading Building Blocks for example.
You have to remeber that now long ago more than 1 cpu was pretty expensive and the only reason Java was made with multicore in mind AFAICT is to sell proprietary SUN multicore cpu/hardware?
Anyways, it the end it comes down to the right tool for the right job and it looks like C++ is jumping on the multicore bandwagon so it's probably to early for Java to celebrate not to mention C/C++ is still pretty much the fastest tool for the majority of things at the moment.
"Therefore, I say that C++ is uniquely positioned to weather this performance storm. Other languages will continue to find uses in application domains that aren't performance-critical, or that are embarrassingly parallel. But whenever the speed at which an individual core crunches stuff matters, C++ will be there. (For example, 3D games. When Halo Infinity is released in 2027 - and yes, I totally just made that up - I fully expect it to be written in C++.)"

[Edited by - daviangel on May 29, 2008 1:54:41 PM]
[size="2"]Don't talk about writing games, don't write design docs, don't spend your time on web boards. Sit in your house write 20 games when you complete them you will either want to do it the rest of your life or not * Andre Lamothe
frob
frob
Quote:
Original post by Koobazaur
Managed languages will definitely keep on improving, but they will not reach the efficiency on non-manged ones, at least not in current state.
That's a fairly circular argument.
Quote:
While JIT can produce bytecode as effective as unmanged, there's still other overhead, the most notable being, obviously, the garbage collector. A GC, while more conviniet, will always be less efficient than good memory management in first place ala C/C++.
This has been debunked for something like eight years now.

Any program that uses a GC system can greatly outperform non-GC systems. In plain C and C++, in the worst case you use the default global allocators -- which are terribly slow. You can improve it with memory pools, which is exactly how GC systems work. GC systems run their cleanup during idle cycles, whereas C and C++ must run the cleanup during their most busy times. Written well, the memory requirements are nearly identical. GC languages can make assumptions about memory aliasing that aren't possible otherwise.

Next, the code generated by your C or C++ compiler will generate code for the lowest common denominator. For Visual Studio, that is currently the Pentium architecture from 13 years ago. You can specifically target to a specific architecture, and even explicitly favor specific Intel or AMD chipsets, but that must all be done at your compile time and is generally a bad thing unless you are creating multiple executables for distribution. JIT, on the other hand, can be configured to target exactly the chipset of the current machine, will transparently optimize for 32-bit or 64-bit (or any other size in the future) architecture.

Note that this is a *can* and not *will* situation. It requires that you understand what is going on, which, sadly, too many programmers fail at. It is true of all languages, not jut Java -- I watched a kid at an interview write a bit of C++ parsing code that consumed all the memory of the PC and wanted to grow the swap file.

[google] can find you lots of good articles detailing performance differences between Java and C++.
Quote:
And sure, you can spare the extra few CPU cycles on a GC when running a ten year old game, but try that with the latest, such as Crysis, and those few extra CPU cycles become a big price to pay.
Perhaps it would surprise you, then, to learn that several big-name games already use C#? How about the fact that mono has been ported to all the console chipsets, and that Ubisoft, THQ, EA, and of course Microsoft, have all said that they are using C# in major games that are due for release this year?
Quote:
Managed languages will always be behind unamanged in performance - they can get close, but they wont be as efficient by very definition.
Very wrong.

Projects like dotNum have found that for some of their numeric processing libraries on a wide range of hardware, the untuned managed code outperformed the tuned unmanaged code versions.

It is more a factor of the skills of the developer and less related to the language used.
Quote:
... but I don't see any of the blockbuster, resource hogging and performance bending game devs switching any time soon, if ever.
There are several big name games from each of the major publishers that are using managed code to some extent. I cannot state game names due to NDAs, but I have firsthand knowledge that they exist, that they are due out this year, and they are all expected to be blockbusters.
OrangyTang
OrangyTang
Quote:
Original post by Metorical
I don't think there's a lot of Java users on GDNET though.

/me points Metorical to my games and my journal.

Back on topic, this is relevant, if a bit ranty. I played the Jake2 applet version and it was very slick (especially the instant switch between applet and full screen display). There were some benchmarks from a while ago that showed Jake2 getting the same fps as the original Quake 2 when run with a modern VM.

A lot of the percieved "java is slow" comes from people using java apps built on Swing (which is slow and laggy, not java itself). Plus the VM start-up time is a slow, which is what causes the slowness to respond in most applets (which is supposedly fixed in the latest VM, but I havn't tried it myself).

Edit: I should point out that the blog i linked to isn't mine, I just happened to be in the same "secret" trial.
capn_midnight
capn_midnight
Quote:
Original post by Metorical
I don't think there's a lot of Java users on GDNET though.

There are, but most of the better ones won't admit it.

Java is a... economically advantageous... skill to learn. I don't have much care to use it in my personal projects, but I have made a good bit of coin using it in enterprise settings.
moosedude
moosedude
Java can perform well, but I've found it takes alot longer and is harder to optimise programs than another language, such as C++.

Some optimisation "tricks" I can do in C++ may also not be applied to Java, I can use pointers for example to reference memory in more efficent ways. It annoys as optimising java seems a bit like witchcraft and guesswork, reducing the number of things you can do to a program, other than algorithm improvements to make things go faster.

Also, in java graphics it really is a pain in the arse to work with graphics at the pixel level; you can do it but its far from efficent.
http://www.fotofill.co.uk
Promit
Promit
Quote:
Original post by moosedude
I can use pointers for example to reference memory in more efficent ways.
Whatever helps you sleep at night, I guess. The rest of us will be over here, doing actual work.

There are a few factors that play into the performance levels:
* Native compilers have been researched, developed, and improved for 40 or 50 years. JIT compilation has optimistically half that time, and with far less people using it. They are catching up, but there's still a long way to go.
* Most people don't understand how GC works, or how to write code that is efficiently garbage collected. People spend many hours writing and tuning custom memory allocators, because the native heap is such shit. Yet when it comes to GCed environments, those same people seem happy to write some naive inefficient code, turn out a badly written program, and then blame the language/JIT/GC/whatever when their badly written code runs badly.
* Somewhat more relevant to games than most software, neither Java nor .NET feels that providing SIMD intrinsics is something worth bothering with. Seriously guys, what the hell?
* There is a complexity trade off. Managed environments do some work to protect you from yourself that the native stuff doesn't. In small programs, it's easy to write correct C/C++ code that doesn't need these protections. As things get larger though, it becomes much, much more difficult to write C code that is stable, safe, and correct. This is where the managed languages pay off -- when you have multimillion line projects with complex interactions between systems and memory flying all over the place, those protections become invaluable.

I still don't believe that any competent C++ programmer really wants to use the language, at least when trying to get things done. (If you just enjoy the skullfuck insanity of C++, that's different.) It's still a necessity for many types of code, for any number of reasons, which is why it continues to be so prevalent. People will continue to shift away from it whenever and wherever possible, whether it be to script systems on top of a small C++ core, or to a purely managed environment, or whatever.

And yes, I'm calling all of you who are happy using C++ for your projects incompetent.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Luckless
Luckless
Quote:
Original post by frob
Quote:
Original post by Koobazaur
And sure, you can spare the extra few CPU cycles on a GC when running a ten year old game, but try that with the latest, such as Crysis, and those few extra CPU cycles become a big price to pay.
Perhaps it would surprise you, then, to learn that several big-name games already use C#? How about the fact that mono has been ported to all the console chipsets, and that Ubisoft, THQ, EA, and of course Microsoft, have all said that they are using C# in major games that are due for release this year?


Might be even more surprising to see just how many games use something like Python to do so much in them. Python, a language known to be 10 to 20 times slower in execution than C++.

Old Username: Talroth
If your signature on a web forum takes up more space than your average post, then you are doing things wrong.
klems
klems
Quote:
Next, the code generated by your C or C++ compiler will generate code for the lowest common denominator. For Visual Studio, that is currently the Pentium architecture from 13 years ago. You can specifically target to a specific architecture, and even explicitly favor specific Intel or AMD chipsets, but that must all be done at your compile time and is generally a bad thing unless you are creating multiple executables for distribution. JIT, on the other hand, can be configured to target exactly the chipset of the current machine, will transparently optimize for 32-bit or 64-bit (or any other size in the future) architecture.
This is often touted as a strength of JIT compilers, but in reality it's fairly irrelevant. On x86, the performance gains to be made by specifically targeting a certain CPU aren't noticable unless you use SIMD instructions to speed things up, which is something you'll have to do yourself anyway since the compiler won't vectorise your code for you.

Quote:
Perhaps it would surprise you, then, to learn that several big-name games already use C#?
How many of them are doing that for performance-critical parts?

Quote:
* Somewhat more relevant to games than most software, neither Java nor .NET feels that providing SIMD intrinsics is something worth bothering with. Seriously guys, what the hell?
Thank $DEITY for that. Once that CPU-specific can of worms is opened, there will be no hope whatsoever of getting any sort of cross-platform compatibility out of Java anymore.
MJP
MJP
Quote:
Original post by Promit
And yes, I'm calling all of you who are happy using C++ for your projects incompetent.


But what if I'm only happy when I'm tearing out my hair trying to track down a memory leak? And producing better code more quickly makes me sad? [crying]




GKW
GKW
Supposedly jre7 is going to have escape analysis with stack allocation, which should give games a nice little speed boost and reduce garbage collection a bit. There is also an outside chance that we will see some form of SIMD autovectorization.
"... we should have such an empire for liberty as she has never surveyed since the creation ..."Thomas Jefferson
Promit
Promit
Quote:
Original post by Valderman
Quote:
* Somewhat more relevant to games than most software, neither Java nor .NET feels that providing SIMD intrinsics is something worth bothering with. Seriously guys, what the hell?
Thank $DEITY for that. Once that CPU-specific can of worms is opened, there will be no hope whatsoever of getting any sort of cross-platform compatibility out of Java anymore.
Intrinsics. As in, functions that can be transparently implemented by the JIT using CPU specific instructions when possible, and falling back to generic implementations otherwise. .NET already does this with several functions in Math.
Quote:
But what if I'm only happy when I'm tearing out my hair trying to track down a memory leak? And producing better code more quickly makes me sad? [crying]
I've got you covered:
Quote:
(If you just enjoy the skullfuck insanity of C++, that's different.)
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
fpsgamer
fpsgamer
Quote:
Original post by Promit
I still don't believe that any competent C++ programmer really wants to use the language, at least when trying to get things done. (If you just enjoy the skullfuck insanity of C++, that's different.) It's still a necessity for many types of code, for any number of reasons, which is why it continues to be so prevalent. People will continue to shift away from it whenever and wherever possible, whether it be to script systems on top of a small C++ core, or to a purely managed environment, or whatever.

And yes, I'm calling all of you who are happy using C++ for your projects incompetent.


By definition shouldn't an expert C++ programmer be perfectly happy using that tool? The problem is (and you actually illustrated this point in your post) that most people aren't expert C++ programmers. The are barely even competent. The problem is that the design of the C++ programming language makes it very difficult to reach that level.

Suscinctly put, C++ isn't a "modern" programming language. Modern languages address things like concurrency, garbage collection etc. None of which C++ does in its current iteration.

Also a curiosity of mine is the fact that several sources mentioned that Java applications were able to out bench native C++ applications on multi-core CPUs? Does this mean they compared a single threaded C++ application against a multi-threaded Java application -- because thats what its sounds like.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.