no JIT 1.3 Variables Strings

- 140 - Integer res; long time = System.currentTimeMillis ; for int j = REPEAT; j 0 ; j-- res = test1i; time = System.currentTimeMillis - time; System.out.printlntest1i took + time; time = System.currentTimeMillis ; for int j = REPEAT; j 0 ; j-- res = test2i; time = System.currentTimeMillis - time; System.out.printlntest2i took + time; ... and the same test for test2i and test1i } public static Integer test1Object o { Integer i = Integer o; return i; } public static Integer test2Integer o { Integer i = Integer o; return i; } } Table 6-3, The Extra Cost of Casts VM 1.2

1.2 no JIT 1.3

HotSpot 1.0 1.1.6 Increase in time None 10 20 ~5 None However, the cost of an object type cast is not constant: it depends on the depth of the hierarchy and whether the casting type is an interface or a class. Interfaces are generally more expensive to use in casting, and the further back in the hierarchy and ordering of interfaces in the class definition, the longer the cast takes to execute. Remember, though: never change the design of the application for minor performance gains. It is best to avoid casts whenever possible, for example by creating and using type-specific collection classes instead of using generic collection classes. Rather than use a standard List to store a list of String s, you gain better performance by creating and using a StringList class. You should always try to type the variable as precisely as possible. In Chapter 9 , you can see that by rewriting a sort implementation to eliminate casts, the sorting time can be halved. If a variable needs casting several times, cast once and save the object into a temporary variable of the cast type. Use that temporary instead of repeatedly casting; avoid the following kind of code: if obj instanceof Something return Somethingobj.x + Somethingobj.y + Somethingobj.z; ... Instead, use a temporary: [4] [4] This is a special case of common subexpression elimination. See Section 3.4.2.14 . if obj instanceof Something { - 141 - Something something = Something obj; return something.x + something.y + something.z; } ... The revised code is also more readable. In tight loops, you may need to evaluate the cost of repeatedly assigning values to a temporary variable see Chapter 7 .

6.3 Variables

Local temporary variables and method-argument variables are the fastest variables to access and update. Local variables remain on the stack, so they can be manipulated directly; the manipulation of local variables depends on both the VM and underlying machine implementation. Heap variables static and instance variables are manipulated in heap memory through the Java VM-assigned bytecodes that apply to these variables. There are special bytecodes for accessing the first four local variables and parameters on a method stack. Arguments are counted first; then, if there are less than four passed arguments, local variables are counted. For nonstatic methods, this always takes the first slot. long s and double s each take two slots. Theoretically, this means that methods with no more than three parameters and local variables combined four for static methods should be slightly faster than equivalent methods with a larger number of parameters and local variables. This also means that any variables allocated the special bytecodes should be slightly faster to manipulate. In practice, I have found any effect is small or negligible, and it is not worth the effort involved to limit the number of arguments and variables. Instance and static variables can be up to an order of magnitude slower to operate on when compared to method arguments and local variables. You can see this clearly with a simple test comparing local and static loop counters: package tuning.exception; public class VariableTest2 { static int cntr; public static void mainString[] args { int REPEAT = 500000000; int tot = 0; long time = System.currentTimeMillis ; for int i = -REPEAT; i 0; i++ tot += i; time = System.currentTimeMillis - time; System.out.printlnLoop local took + time; tot = 0; time = System.currentTimeMillis ; for cntr = -REPEAT; cntr 0; cntr++ tot += cntr; time = System.currentTimeMillis - time; System.out.printlnLoop static took + time; } } Running this test results in the second loop taking several times longer than the first loop see Table 6-4 . - 142 - Table 6-4, The Cost of Nonlocal Loop Variables Relative to Local Variables Times Relative to Loop Local Variables 1.2

1.2 no JIT 1.3