new Object
119,000 per secondnew C()
(class with several methods) 89,000 per secondo.f()
(method f
invoked on object o
) 590,000 per secondo.sf()
(synchronized method f
invoked on object o
) 61,500 per second
Thus, we see that creating a new object requires approximately 8.4 msec, creating a new class containing several methods consumes about 11 msec, and invoking a method on an object requires roughly 1.7 msec.
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, the Java bytecodes can be translated on the fly (at run time) into machine code for the particular CPU on which the application is executing. For those accustomed to the normal design of a compiler and dynamic loader, this 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++.
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.
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.
Now We Move On to the HotJava World-Wide Web Browser
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.
The Java(tm) Language Environment: A White Paper