java performance
by Glen McCluskey
Glen McCluskey is a consultant with 15 years of experience and has
focused on programming languages since 1988. He specializes in Java and
C++ performance, testing, and technical documentation areas.
In Java, all class types are directly or indirectly derived from the superclass Object. Primitive types such as int or double are not class types and do not have this property. But they do have class type wrappers that can be used to represent the primitive type and hence plug in to the Object hierarchy. For example, the wrapper for int is Integer:
Integer x = new Integer(37); In this example, I've taken an integer constant (37) and created a class object instance to represent this value. The object instance can be assigned to an Object reference and manipulated in various ways, such as representing a set of values in a Vector. Wrappers also offer other services beyond representation, such as conversion between strings and values of a primitive type (for example, Integer.parseInt()), and representation of the minimum and maximum values of a primitive type (such as Integer.MIN_VALUE and Integer.MAX_VALUE). Wrapper Overhead Wrappers have some overhead associated with them. They offer generality at the cost of inconvenience in digging out the value: int i = ((Integer)p).intValue(); There are some space costs as well. To more closely examine this latter point, we can write a program that allocates a Vector of ints or int wrappers, and compute the size of each Vector element: public class test1 { public static final int N = 25000;
public static long freemem() // ints without wrappers
public static void test01() int vec[] = new int[N];
for (int i = 0; i < N; i++)
long end_mem = freemem();
System.out.println("bytes per element = " + n);
// ints with wrappers
public static void test02() Integer vec[] = new Integer[N];
for (int i = 0; i < N; i++)
long end_mem = freemem();
System.out.println("bytes per element = " + n);
// driver
public static void main(String args[]) } This program uses a system method freeMemory() that returns the amount of memory currently free. Note that this technique for determining memory use per element should be employed very cautiously, given the vagaries of garbage collection and so on. When we run the program, it reports 4 bytes used per element without wrappers and roughly 16 per element with a wrapper. A wrapped double reports as 24 bytes per element, with the actual double value as 64 bits (8 bytes). The space overhead of wrappers goes to support system features such as garbage collection. Allocating a dynamic object in Java has similar overhead to allocating a block of space in C using malloc(). Wrappers have considerable advantages in that primitive types can be treated in a way similar to class types. See, for example, the discussion on page 243 of Arnold and Gosling's book The Java Programming Language (Addison-Wesley). But they do take extra space and time, which may be an issue in some applications. Arrays of Primitive Types If you're interested in manipulating arrays of primitive types directly, without use of wrappers, newer versions of Java (1.2) offer basic sorting and searching capabilities for such arrays. For example, to sort an array of integers, you can say this: import java.util.Arrays;
public class test2 { Arrays.sort(vec);
for (int i = 0; i < vec.length; i++) Arrays.sort() takes a reference to an array. The array includes an internal length descriptor, and is sorted in ascending order upon return. java.util.Arrays is a class loosely associated with the set of Collection classes offered in Java 1.2. Arrays.sort() can be applied both to arrays of primitive types, and to arrays of standard wrapper objects such as Integer and Double. The sorting logic in the Arrays class is duplicated for each primitive type. Note that a language like C++ solves the wrapper/sorting problem in a different way, by use of a sort() template and by assuming the existence of a built-in or user-defined operator like "<" that is used to order array elements, both for elements of primitive type and for elements that are class objects. Templates and operator overloading represent a more general solution to the problem of sorting arrays of elements, but at the same time are more complex and harder to understand and implement.
|
|
First posted: 13th November 1998 jr Last changed: 13th November 1998 jr |
|