Blogpost about Java for Game Programming

Hi there,

I just wrote a small blog post about my experience in working with Java for game programming. It is mostly things I stumbled upon while working on Caromble! for the last few years.
Check it out: http://www.goo.gl/GD7nm

Grts!

Peter

Intresting read, thank you!

I think this might be the wrong section to post this.

Yes, articles&tutorials is for tutorials not links to tutorials.

Moved from Articles & Tutorials to General Discussions :point:

Really nice article focusing on the primary pain points without digressing into off-topic ramblings. I also like the concluding message (at least my interpretation of it): the tool does not do the job, you do.

What you wrote about Java and C++ in terms of performance is simply wrong, these are just prejudices. Java has been able to become even in some cases a bit faster than C++ during the last 10 years. Don’t blame Java. If you get worse performance, it will be probably mainly your fault. I used a lot C and a bit C++ before switching to Java once for all; if it was really slower, I would still code in C.

Objects pooling is often inefficient since Java 1.4 except in a few very particular cases and I get excellent performances without using Java 1.7 try construct. You advise to call System.gc() between levels which is a really bad idea even in this case, it can cause a lot of troubles in the JVM cache. What you wrote about direct NIO buffers is very incomplete, you must release the native memory they use by yourself if you don’t run out of memory on the Java heap, not on the native heap, I already wrote about that in my blog. Moreover, I modified Ardor3D so that you can free the memory allocated by this kind of buffers when used in VBOs in the renderer, you can simply override the method deleteVBOs(final AbstractBufferData<?> buffer) and call it between levels for example.

Thank you for your feedback.

I really didn’t want to go into discussions about Java vs other programming languages -there’s already enough information to find on that elsewhere. I merely wanted to help people that are (planning to) write games in Java with things I learned along the way.

Agreed, you only need to consider pooling objects once you have problems with garbage-collector-stutters in your game. And even then, you probably only need to implement pooling in a hand full of methods to solve these issues.

We use the Java 1.7 try construct purely for convenience, it makes sure that once the temp object goes out of scope its gets returned to the pool (instead of manually calling pool.push()). This is especially useful when you have multiple return statements within the scope of the temp object.

Well that is all a bit out of scope of the article. The only point I was trying to make is that you need to be more careful with Directbuffers in Java than with ordinary objects; garbage collecting them will lead to stutters in your game a whole lot sooner than with normal Java objects (and they are harder to find with the Java Visual VM as well).

Grts,

Peter

In my humble opinion, if you’re unable to prove that, don’t write than Java is really slower than C/C++/whatever. There is no consensus about that. Doug Lea’s (biased?) microbenchmarks and the reactions it caused illustrate what I mean.

They will be garbage collected if and if only you run out of memory on the Java heap whereas they allocate memory on the native heap. If you run out of native memory, your game will simply stop working which is worse than some stutters :(. You say in your article that we need to be more careful with direct NIO buffers but you miss the main point. Reusing direct NIO buffers is a good idea but it is not enough and it is not always possible. Several JMonkeyEngine and Ardor3D users already ran out of native memory. However, I have to admit that explaining how to handle direct NIO buffers is not easy. I would advise to avoid unnecessary duplication of data (not only in this kind of object) including mesh data (you already wrote that), use slicing when it is possible, favor indirect NIO buffers when direct NIO buffers are not absolutely necessary (for example when they are not used for OpenGL) and to free the native memory they use when you’re sure of what you’re doing. My last suggestion is very important especially if your game doesn’t use a lot of memory on the Java heap.

The performance in Java depends greatly on how well the compiler and runtime can optimize your code and application. A recent Minecraft fix greatly improved performance because a certain piece of code that was basically executed for every drawn block was head-butting with the optimizer. If the optimizer can do its job well, you might even see more sparks flying than a similar native application.

The question is: how do you make sure you do not get in the way of the optimizer? That requires intimate knowledge I’m afraid, which hooks back into my favorite saying: programming is and will always be hard. You just don’t get it for free.

[quote]The algorithm was simplest to implement in Java, but garbage collection settings make both Java and Scala difficult to benchmark accurately.
[/quote]
The most important point I think is: who cares? Maybe for some highly specific cases in which you have to squeeze out every last drop of performance this may matter. But I don’t think it matters at all for 99.99% of the games out there, and people should choose the language they like and are most productive with.

Excellent question, often goes side by side with “you ain’t gonna need it”.

Yay for scala being the second! :slight_smile:

Some quotes from the PDF (and some reasons for learning scala):

Also, in the graph the ‘scala pro’ version (written from an experienced scala programmer, 2nd fastest code in the benchmark) had the least lines of code. Only 297. Almost 3 times less than C++ and almost 4 times less then Java (java was the worst, btw)…

Another interesting quote - not about ‘use scala’ this time:

And now - again about scala - that is very, very interesting:

And finally, I like the conclusion:

Now, thats enough for todays ‘learn scala’ screaming. Sorry for that, but … yeah…
:smiley:

It’s not a reason to write approximate things. I give some references in my articles.

[quote]The algorithm was simplest to implement in Java, but garbage collection settings make both Java and Scala difficult to benchmark accurately.
[/quote]
The most important point I think is: who cares? Maybe for some highly specific cases in which you have to squeeze out every last drop of performance this may matter. But I don’t think it matters at all for 99.99% of the games out there, and people should choose the language they like and are most productive with.
[/quote]
IBM draws different conclusions in HPC (IBM engineers conclude Java beats Fortran except in scalability) and I have no trouble believing that smart Java code can blow C++ out of the water in more and more cases.

An unsafe language like C++, or really more the C parts of it, can technically outrun any managed language runtime like Java, because they can bang on arbitrary memory to write almost any instruction sequence they want, and that’s without embedded assembly. The problem is, how much effort does that take for how much actual payoff, and what are the bugs that are created when the results of the effort aren’t 100% perfect?

+1 to what sproingie just said.

Heck, in C++ you can even have assembler blocks if you’re that kind of maniac, but again, requires more effort and care on the part of the programmer to avoid making the computer explode.

My personal philosophy regarding languages is that it’s not the tool that makes the project, but the programmer’s skill.

I’m kind of pressured into that mindset, since in my line of work, I’m actually forced to use specific programming languages for specific devices, and performance is expected to be the same regardless.

Great article! Both entertaining and informative.

At the end of nineties, C/C++ fans gave the same kind of arguments to explain that as Java is written in C (Jikes was written in C++), it can’t outperform C which is wrong. One of my teacher wrote a program that converted Java (1.3) to C code during his thesis and he only obtained a very small gain (less than 5%) after years of work. Brian Goetz explained that memory allocation and method calls are between 2 and 4 times faster in Java. I really think that almost no human being is able to write a better machine code or assembler code that a compiler like GCC except in particular cases on a small piece of source code and if you really believe you can be more efficient than the JVM, don’t use Java. I’m sad to see these kinds of prejudices about Java even here on JGO.

No one use standard memory allocator for performance critical code and inlined method have zero method call overhead.

[quote=“gouessej,post:18,topic:41685”]
And I’m sad about statements like this one, which implies two very wrong things:

  • That people approach languages based on prejudice rather than on rational assessment.
    If actual verifiable proof is presented of one language outperforming the other, then that’s that. But way too often I see that proponents of either “side” are careful to ignore or outright dismiss whatever piece of evidence is presented that contradicts them.
  • That participating in JGO somehow makes you part of the “team” and your opinions have to conform to that of others.

Again, programming languages are tools, and discussing their strengths/weaknesses is fine. But when people start taking it personally, then it’s time to take a step back.