This chapter addresses two issues of interest to prospective adopters of Java, namely, what is the performance of Java, and how does it stack up against other comparable programming languages? Let's first address the performance question and then move on to a brief comparison with other languages.
Java has been ported to and run on a variety of hardware platforms executing a variety of operating system software. Test measurement of some simple Java programs on current high-end computer systems such as workstations and high-performance personal computers show results roughly as follows:
||119,000 per second
||89,000 per second
||590,000 per second
||61,500 per second
Thus, we see that creating a new object requires approximately 8.4 µsec, creating a new class containing several methods consumes about 11 µsec, and invoking a method on an object requires roughly 1.7 µsec.
While these performance numbers for interpreted bytecodes are usually more than adequate to run interactive graphical end-user applications, situations may arise where higher performance is required. In such cases, Java bytecodes can be translated on the fly (at run time) into machine code for the particular CPU on which the application is executing. This process is performed by the Just In Time (JIT) compiler. For those accustomed to the normal design of a compiler and dynamic loader, the Just In Time compiler is somewhat like putting the final machine code generator in the dynamic loader.
The bytecode format was designed with generating machine codes in mind, so the actual process of generating machine code is generally simple. Reasonably good code is produced: it does automatic register allocation and the compiler does some optimization when it produces the bytecodes. Performance of bytecodes converted to machine code is roughly the same as native C or C++.
There are literally hundreds of programming languages available for developers to write programs to solve problems in specific areas. Programming languages cover a spectrum ranging across fully interpreted languages such as UNIX Shells, awk, TCL, Perl, and so on, all the way to "programming to the bare metal" languages like C and C++.
Languages at the level of the Shells and TCL, for example, are fully interpreted high-level languages. They deal with "objects" (in the sense they can be said to deal with objects at all) at the system level, where their objects are files and processes rather than data structures. Some of these languages are suitable for very fast prototyping--you can develop your ideas quickly, try out new approaches, and discard non-working approaches without investing enormous amounts of time in the process. Scripting languages are also highly portable. Their primary drawback is performance; they are generally much slower than either native machine code or interpreted bytecodes. This tradeoff may well be reasonable if the run time of such a program is reasonably short and you use the program infrequently.
In the intermediate ground come languages like Perl, that share many characteristics in common with Java. Perl's ongoing evolution has led to the adoption of object-oriented features, security features, and it exhibits many features in common with Java, such as robustness, dynamic behavior, architecture neutrality, and so on.
At the lowest level are compiled languages such as C and C++, in which you can develop large-scale programming projects that will deliver high performance. The high performance comes at a cost, however. Drawbacks include the high cost of debugging unreliable memory management systems and the use of multithreading capabilities that are difficult to implement and use. And of course when you use C++, you have the perennial fragile superclass issue. Last but definitely not least, the binary distribution problem of compiled code becomes unmanageable in the context of heterogeneous platforms all over the Internet.
The Java language environment creates an extremely attractive middle ground between very high-level and portable but slow scripting languages and very low level and fast but non-portable and unreliable compiled languages. The Java language fits somewhere in the middle of this space. In addition to being extremely simple to program, highly portable and architecture neutral, the Java language provides a level of performance that's entirely adequate for all but the most compute-intensive applications.
Prospective adopters of the Java language need to examine where the Java language fits into the firmament of other languages. Here is a basic comparison chart illustrating the attributes of the Java language--simple, object-oriented, threaded, and so on--as described in the earlier parts of this paper.
From the diagram above, you see that the Java language has a wealth of attributes that can be highly beneficial to a wide variety of developers. You can see that Java, Perl, and SmallTalk are comparable programming environments offering the richest set of capabilities for software application developers.
Very dynamic languages like Lisp, TCL, and SmallTalk are often used for prototyping. One of the reasons for their success at this is that they are very robust--you don't have to worry about freeing or corrupting memory.
Similarly, programmers can be relatively fearless about dealing with memory when programming in Java. The garbage collection system makes the programmer's job vastly easier; with the burden of memory management taken off the programmer's shoulders, storage allocation errors go away.
Another reason commonly given that languages like Lisp, TCL, and SmallTalk are good for prototyping is that they don't require you to pin down decisions early on--these languages are semantically rich.
Java has exactly the opposite property: it forces you to make explicit choices. Along with these choices come a lot of assistance--you can write method invocations and, if you get something wrong, you get told about it at compile time. You don't have to worry about method invocation error.
From the discussion above, you can see that the Java language provides high performance, while its interpreted nature makes it the ideal development platform for fast and fearless prototyping. From the previous chapters, you've seen that the Java language is extremely simple and object oriented. The language is secure to survive in the network-based environment. The architecture-neutral and portable aspects of the Java language make it the ideal development language to meet the challenges of distributing dynamically extensible software across networks.
These first eight chapters have been your introduction to the Java language environment. You've learned about the capabilities of Java and its clear benefits to develop software for the distributed world. Now it's time to move on to the next chapter and take a look at the HotJava World-Wide Web browser--a major end-user application developed to make use of the dynamic features of the Java language environment.