足彩总进球数玩法:Why Java can be used for games
by Jacob Marner
Originally written June 15th, 2000. Last edited August 16th, 2001.
足彩总进球数二三球 www.ngfcl.com (Note: If you have read this article before you will see that the conclusions has changed and old outdated links are removed. This is because Java technology has improved since the article originally was written and many of things no longer was true. This article view of Java is based on the use of Sun's JDK 1.3.1.)
Often when I tell people that I am writing a game in Java they sniff and say something like "You must be kidding; Java is too slow", "Real men don't program Java", or "Java is not a real programming language". This opinion is very often caused by the fact that those people only have tried to run a Java applet in their browser and have seen that it runs very slowly.
In the following I will clear up some common misconceptions and make sure that you understand that Java really is useful for game programming and C++ is not the only choice. I am not saying that C++ is bad or anything; just that using Java for a gaming project can be a real benefit that should not be missed.
This articles is generally targeted at C++ programmers that are wondering or skeptical about whether Java can be used for professional games.
To understand this article you need some general programming experience and at least a basic knowledge of C++. Some basic knowledge of Java is also required, but reading a small tutorial somewhere should be enough.
This article assumes that the goal is to write high performance games similar to those boxed ones being released commercially for sale in stores. The target platforms we are interested in are the PC and consoles.
Also, we will not compare Java with other high level languages such C# or Visual Basic .NET, but merely consider Java when compared with the de facto game development language of today: C++.
Start by opening your mind
If you are a C++ programmer then you are probably very tired of all those Java evangelists back in 1995 claiming that Java is superior is every regard and that 100% pure Java is the best thing there is. Chances are that you tried it back then, saw how awfully it ran, and the dismissed it as a web development toy.
Fortunately most the hype surrounding Java has since then died out and the compilers and virtual machines has improved significantly.
We will now try to figure out what Java really is useful for.
I have heard the same hyped arguments and originally dispelled the use of Java as anything but a web applet language because of the many promises that was clearly not true. After all, if something needs justification then it is usually not worth the effort - usually.
And if you do a quick web search on "Java games" you get nothing but small crappy applets that nobody cares about. These are actually making the reputation of Java gaming worse, because you and many other people get the impression that that is the only thing Java can do.
However, all this does not means that Java is useless for all gaming purposes. In this article I will argue that Java does in fact has it uses within gaming and can help you build better games with less effort.
The advantages of using Java
I have heard other people say that they do not want to switch to Java from C++ because there is not benefit in doing so, especially since we by using native code loose the main Java benefit of cross-platform programming. That is very wrong.
Java and C++ look alike on purpose to make the transition easier to make for C++ programmers but this is only on the surface. Many things are easier in Java than in C++. A few is mentioned below. If you disagree on some of these points please read this in-depth discussion.
Some people complain that Java is actually missing some of the features that they need. Most of them you are actually better left without:
You may think that the advantages of Java may seem very few and if you are very productive in C++ you may think that you can live without them. I thought so myself before changing to Java in 1999. I was surprised how much faster development in Java really is. You really have to try Java before judging it.
IDC have made a large study that shows that Java applications written in 100% pure Java yield a 25% overall time/cost saving and 40% in the coding phase. The reduction in costs of code maintenance was around 30%. I am not sure exactly how big the reduction is for games, but it is a fact that Java increases your productiveness both by increasing code writing speed but also by reducing the number of bugs. This assertion is based both on my personal experience with both Java and C++ but also on a number of articles/studies.
According to Jeff Kesselman (a Sun Java engineer and ex-game developer) most Java game developers report a productivity gain of a factor of 2 to 4.
Myth: Java is slow!
No this is not true, except in some cases and it is these cases that has given Java a reputation for being slow.
The cases when Java is slow
It is very true that interpreted Java applets in modern browsers are very slow. Often a factor of 10 or more than C++ programs. You have probably experienced this first hand by playing some small games in on some web page through your browser. In this environment it is true that commercial-class games will never see the light of day.
Browsers use an old version of the Java technology that is very slow compared to what is possible today. The last couple of years major improvements has been gained in the speed of Java that makes almost as fast as C++ code. Today's interpreters actually internally compile the code to machine code and even use information gained at run-time to do run-time optimizations on the code.
You may also have run your own tests using Microsoft J++. Judging Java based on that is not fair, since that is one of the slowest versions you can get of Java. (We know how Microsoft and Sun feel about each other, don't we?)
You may have tried Java applications outside your browser and found them slow too. This is because the Java Windows system (mainly Swing) is cross platform and therefore draw all the windows controls manually. This is very slow. However, since games usually does not contain a lot of windows and other widgets this is really not a problem for games.
In all other cases Java is fast!
Modern Java programs are not slow (here we are talking about Java virtual machines 1.3 or later). They more or less run the same speed as C++ programs. However this assumes that they are well-written. Java programs must be written using a clean object oriented approach, otherwise they will suffer.
A rough estimate would say that current typical Java games rare approximately a factor of 1.5 to 2 slower than what is possible with C++ depending on the application - I have made no formal tests so this estimation is based on the performance I see in games.
This is due to either of two reasons:
For some actual bench marks that compares C and Java and than supports this see Runtime Vs Static Compilation - Performance Comparison. This benchmark is a year old. As you can see the result vary a lot depending on the application but overall Java does not place bad.
People often say that Java cannot compete with hand optimized C++ code. This is also wrong. But of course this also assumes that the Java code is also hand optimized. As with any language Java has its pros and cons and as any good programmer you should know what is fast and what isn't.
A common misconception is that Java does not run compiled code. Although it reads byte code it also compiles and optimizes that code based on run-time information and the architecture it is running on. No C++ can do that! This means that, although it is not the case today, that Java virtual machines very well may get more efficient than C++ code. If you meet somebody telling you otherwise they probably don't know about the recent advances in technology making all this possible.
If you want to know about all the cool stuff the Java virtual machine is capable of I recommend reading The Java Hotspot Performance Engine architecture white paper.
But why is most of the Java applications I see so slow then?
And remember, if somebody shows you a slow Java program then it is likely one of the following things are happening:
The first case, that the program is poorly written, happens more often than you think. Although I cannot back the following up I believe that it has to do with:
In conclusion the main reason that Java programs are slow is that developers don't know how to use it properly. Writing efficient programs can be bit tricky especially since many of the optimization "truths" you know from C++ no longer is true in Java due to adaptive optimizer. That said, during optimization in Java is generally much cleaner than in C++ that usually get very messy when you optimize heavily. Java is designed to work best with well-designed clean object oriented program.
Static native code compilers
Some companies has created native code compilers for Java, i.e. compilers that convert Java source code directly to a static machine code executable just like C++ compilers do. They simply consider Java to be yet another language that you can program in. Native code compilers are also called static compilers.
When running programs compiled with a native code compiler the program is not interpreted and does not need a Java run-time environment (JRE), although some run-time DLLs may be needed. (Note that some native code compilers require the final executable to use Sun's Java DLLs. This this case, due to JRE license restrictions, the full JRE must be be distributed with your application even if it is not used.) Native code compilers create regular *.exe files and even *.dll files.
Several good native code compilers exist out there. These include:
My favorite is Excelsior Jet. A time-limited evaluation version is available for download from Excelsior. If you intend on maintaining a zero-budget then the only option is GCJ, but that is a little more complicated to use.
And just to set something straight:. The following Java compilers/IDEs do NOT include a native code compiler. Some such as Webgain Visual Cafe claim that they do, but they merely include wrappers that but interpreted code into and exe file.
Most of the mentioned Java native code compilers, support everything that you are used to from Java including all the standard libraries, AWT, Swing and all the standard extensions (such as Java3D). You can even import byte code supplied by 3rd party developers and compile them directly to native code. The only thing that you cannot make is native code applets, but this would not make much sense anyway.
Java has the advantage of being a simple language, which means that optimization has greater potential than in C++, which is a fairly complex language with many special cases that makes optimization hard to do, so you can expect to see even better Java compilers in the future - possibly generating faster code than those C++ compilers we know today.
For the record, it should be noted that native compilation does not come without a price. If you use native compilation you loose some Java features:
But is native code compilers faster than using a hotspot virtual machine? Often. Try it out for your application. However, in the long run hot spot virtual machines are going to win because they optimize the game automatically to take care of the architecture it is running on. If, for instance, a static compiler compiled it for a Pentium 2 and it is run on a Pentium 3 performance will suffer. This will not happen with a hotspot virtual machine.
Some Java evangelists will claim that Java virtual machines are always just as fast as native code but this is simply not true today. If you disagree on this I recommend reading The Java Performance Report (August 2001 Edition) which is an independent bench mark comparing the compilers. This report also explains some of the benefits of native code compilers. I do admit, however, that the gap between native code compilers and regular virtual machines has closed much in the last years and the reason to use them are smaller than before.
Myth: Garbage collection
I often hear people say that they dislike the idea of a garbage collector that may kick in at any time and pause the system for a few seconds. That would admittedly be a bad thing in many cases, because everything would hang in the meantime. Not a good thing in a high-performance real-time game. Fortunately, due to recent improvements in garbage collector technology they is nothing to be afraid of since the risk of that happening is very low.
Garbage collection is not inherently slower at execution time than manual deallocation. It is actually often faster since you (depending on the schemes used) more easily can avoid memory defragmentation on the heap or often can reduce the overhead of deallocating object. Remember; when you use a garbage collector then the system does not have to use time to deallocate the object when you are done as it has to in C++; the cleaning methods only use time with the objects that you keep; if you have a lot of small objects that are temporary deallocation takes zero time for those!
Be warned there is several pages about garbage collection on the net. These claim that garbage collection is slow. This is usually because they have evaluated slow schemes. Ground research in the last few years a found results to make this untrue. In fact comparing with the explicit deallocation in C++, garbage collection is much faster. It should be noted, that it also needs to be since Java programs generally do more allocations than C++ programs.
For those of you with some knowledge of garbage collection should know that Java today uses a generational garbage collector with very fast new-space (nursery) combined with a old-space that runs either a mark-compact garbage collector or an incremental garbage collector, depending on options given to the virtual machine at startup.
For more information about garbage collection see Richard Jones' The Garbage Collection Page.
Myth: Java does not support native Windows, DirectX or OpenGL!
Java comes with an interface called JNI (Java Native Interface) that lets Java communicate with external *.dll files and *.obj files. This is actually how the libraries included with Java itself is written. This means that you can call (or be called by) Windows, DirectX or any other C/C++ library absolutely without problems. This also means that if you a changing to Java you can still utilize any library you may have written in C/C++.
Unfortunately, in an effort to be portable, JNI is pretty slow and the use of it should be minimized. So when designing the interface between C++ and Java an effort should be made to avoid calls over the boundary. This can be done by putting code on the C++ side to make the interface more high level. For instance, if you intend to use OpenGL you might be better of writing some high level primitives in C++ in order to bundle calls.
Like all other optimizations this can be postponed until a late state in the project, however it is generally a good idea to access C++ in a high level, i.e. let each JNI call have a large amount of functionality to help reduce the overall number of calls.
Myth: You can't write Java programs for game consoles!
Wrong again. It is true that there are no Java virtual machines available for the Nintendo 64, Sony Playstation or the Sega Dream cast, but because GCJ (the Java GNU compiler) can run on any platform that has a port of gcc and because gcc ports exist for the consoles you can in effect write efficient GCJ programs for consoles.
The main drawback of using GCJ is that it only supports Java 1.1 and support for inner classes are at the time of writing still experimental, but GCJ is getting better all the time so this problem will likely be gone soon.
However things look to be much better around the middle of 2002. Here the first implementation of the Java Game Profile will be ready. This is a standard interface that allows implementing Java platforms to run games in a standardized and portable way, i.e. games will be able to be ported between consoles and other gaming devices very easily.
Myth: Java is slower than C++ because...
Java can't allocate objects on the stack
Yes in the old days a garbage collector was slow but not today. Java uses a so-called generational garbage collector. In short this divides the heap into two sections. One for short-lived objects, called the nursery, and one for long-lived objects. Objects are allocated in the nursery. This is always compacted so allocation of new objects is usually just the matter of moving a pointer in memory. Deallocation occurs when the nursery is full and then only the objects still alive are even touched. So if the program has many small objects which mostly is short-lived temporary ones then deallocation is practically free (it is not completely free since many objects fill the nursery faster). So in practical terms this is often faster than C++. Read more about the garbage collector here The Java Hotspot Performance Engine architecture white paper.
Java program run interpreted
Yes in 1995 and 1996, but not today. Hotspot virtual machines and static native compilers both compile the code to machine code before it is run (JIT compilers did the same, but was just not very efficient).
Hotspot compilers use what is called adaptive optimization. This means that it analysis the code at run-time and compiled and optimizes it then. Since this allows optimization not possible in static compilers these have the potential of get faster than C++ compilers. It should be noted that C++ compilers are unlikely to adopt this technology is C++ is a complex language, which making the creation of such compilers virtually impossible to do.
Java can't do global optimization
Because Java contains support for dynamic class loading this is true using traditional compiler techniques. But hotspot is not traditional. In fact since optimization is done at run-time it can easily do global optimization. If one or more of the classes involved are suddenly changed then the optimization will be redone.
The optimization then uses all the traditional optimization techniques on the result:
More will likely be added in the future. Note also that programs often run faster after having run for some time since more and more code is being optimized while it runs.
Java requires many dynamic casts and virtual method calls
See the above section on Java and global optimization. The optimizer handles both these situations so both dynamic casts and virtual method calls become very cheap, or even free in some cases.
Java has range checking and null pointer checks
See the above section on Java and global optimization. The optimizer handles both these situations so they even some time can be eliminated fully.
There is many people telling my it is slow, so it must be
Usually, people only tried Java at a time it was slow or tried using applets or even Swing applications. This given Java a reputation for being slow that is not correct today. A lot of old articles about Java remain on the Internet that keep this myth alive - those articles are targeted at old versions of Java. They are no longer true.
Myth: No commercial games use Java!
All these arguments is worth nothing if there is no actual proof that it is possible to write high performance games in Java. Below is a list of those I know about.
Also in most development areas Java is gaining heavy ground. For some reason game developers are slow to follow suit. However, game developers was also slow to embrace C++ when that came out, so this is probably no surprise. Read this ZDNet article from 16th August 2001 referring to an IBM survey about what programming languages people use.
One example of Java in games is the highly acclaimed game Vampire - The Masquerade from Nihilistic software. This game uses Java as its s cripting engine (i.e. control code) and has its engine written in C++ and is therefore an example of mixed code. This game runs with very high performance. According to the Gamasutra postmortem of Vampire, Nihilistic Software very satisfied with using java in it (and this was in interpreted Java 1.1 which much slower than what is possible today).
Also noteworthy is the best selling Who wants to be a Millionaire. Here the logic was written in Java and the rest in C++.
Of other commercial games using this scheme (logic in Java) can be mentioned You don't know Jack and Majestic.
On the freeware scene a few games are worth trying. Take a look at Arkanae. It uses the free Java based 足彩总进球数二三球 3D engine. This cool freeware game runs better than most C++ games. The engine is written on the C++ side using only the free library gl4Java, a popular and portable OpenGL wrapper for Java. This wrapper uses JNI a lot so it should be possible to increase performance even more. gl4Java is a good example of a library that can be used for games directly.
You should also