Java Reference
In-Depth Information
There are some optimization steps that you can make to improve the per-
formance of your programs. For example, if you are sure that you will not be
overriding a method then you should you use the modifier
final
. The compiler
can then
inline
the method and the interpreter will not have to search for possible
overriding methods. Inline puts the program code directly in the execution flow
and therefore avoids jumping to and from another section of memory.
When you are unsure about the relative speed of different coding techniques,
you can test them with the static method
System.currentTimeMillis()
.
This method returns a
long
value equal to the number of milliseconds since a
standard date in 1970. That number in itself is of little value, but the difference
between two millisecond time readings can be meaningful. Thus, you can bracket
a code section of interest with this method and find the difference in milliseconds
to get an idea of how long that section of code takes to run.
Note that on today's high-performance machines, you often need to loop
over an operation a large number of times to produce a time in the millisec-
ond range. Such a timing measurement has come to be known as a microbench-
mark and is fraught with difficulties for a variety of reasons, including just-in-
time and dynamic compilation techniques, compilation warm-up periods, the
use of separate compile threads, background compilation, compiler optimiza-
tions, dead code removal, and others. Nevertheless, many people still rely on
System.currentTimeMillis()
to measure execution time differences. We
explain here how that is normally done and attempt to ameliorate many of the
concerns that make microbenchmarks untrustworthy.
With multiprocessing happening in the operating system and multithreading in
the JVM, the measured times will vary from run to run, so a statistical average is
more meaningful than a single run. It is wise to unload any unnecessary programs
that might steal time slices away from the program you are testing.
As an example, consider the
java.util.Vector
class we discussed in
Chapter 10. It is often very useful compared to a regular fixed-length array because
of
Vector
's ability to remove and add elements. However, in situations where
high performance is required, you may find that an array is preferable because
Vector
offers noticeably slower performance than an array. One reason that
Vector
is slow is because it is synchronized for thread safety. An alternative
that can be used in most situations is the
ArrayList
class which does not have
the synchronization overhead. In the test code below we compare timings of
object arrays,
Vectors
, and
ArrayList
objects. For consistency, we populate
each with
Integer
objects.
In the
main()
method shown below in the class
TimeTest
,weread in
some command line parameters and then call
doTests()
several times. Inside
doTests()
we call four methods that test fetching
Integer
objects from four
different container types -
Vector
,
ArrayList
,regular object arrays, and
an
ArrayList
<
Integer
>
collection object that takes advantage of the new
generics feature in Java 5.0 (see Chapter 10). If you want to run this code on a
pre-5.0 Java system, you'll need to comment out the generics version.
Search WWH ::
Custom Search