Ibm just-In-Time Compiler (jit) for Java: Best Practices and Coding Guidelines for improving Performance



Yüklə 153,14 Kb.
Pdf görüntüsü
səhifə5/7
tarix07.11.2018
ölçüsü153,14 Kb.
#78937
1   2   3   4   5   6   7

 

 

 



When the Java application is highly polymorphic (complex class hierarchy), then it is more efficient to 

use abstract types, rather than interface types, as interface calls are more expensive. For interface 

calls with few implementations, the TRJIT compiler attempts to use an if-then-else chain (called 

Polymorphic-Inline-Cache) [8] to compare the receiver types for faster interface dispatch. Figure 8 

shows an example.  

o = receiver object ;  

x = receiver class (o) ;  

if ( x == expected-class-1 )  

 

x.foo(a, b, c) ; 



      // implementation of foo from class-1 

 

else if ( x == expected-class-2) 



 

x.foo(a, b, c) ; 

      // implementation of foo from class-2 

 

else if ( x == expected-class-3) 



 

x.foo(a, b, c);           // implementation of foo from class-3   

 

else  


 

o.foo(a, b, c);           // checks failed, interface call 



Figure 8. Example of Polymorphic Inline Cache 

 

Guideline: Use exceptions and reflection rarely 

To provide the best possible performance of the application in the common cases, the VM and the JIT 

optimize the non-exception paths of the application in favor of the exception paths. Throwing an 

exception is expensive because of the associated runtime overhead. Therefore, exceptions should 

not be used for normal flow-of-control in a Java application. 

The Java reflection API provides a simple interface for you to obtain information about various 

classes, methods and objects of the application when it runs in the JVM. However, reflection 

introduces additional levels of abstraction and indirection that affects application performance. You 

should not use reflection in the core of a performance-critical application. Figure 9 and Figure 10 

show an example and the performance cost that is associated with using reflections. 



IBM Just-In-Time Compiler (JIT) for Java 

Best practices and coding guidelines for improving performance 


 

 

 



 

 

public int invokeDirect() { 



        int sum = 0; 

        for (int i = 0; i < N; i++) { 

         

sum = increment(sum); 

        } 

return sum; 

 

public int invokeReflect() { 



try { 

 

 



Class c = Class.forName("reflectTest"); 

 

 



Method m = c.getDeclaredMethod("increment", new Class[]{int.class}); 

  // 


create 

the 


args 

array 


 

 

Object [] args = new Object[1]; 



  // 

init 


the 

sum 


 

 

Object sum = new Integer(0); 



 

 

for (int i = 0; i < N; i++) { 



   args[0] 

sum; 



   sum 

m.invoke(this, 



args); 

 

 



  return 

((Integer)sum).intValue(); 

 

} catch (Exception e) { 



System.out.println(e); 

       return 0; 





Figure 9: Example of using reflection 

 

Loops 



Loops are an integral part of the Java programming language. For many programs, a good majority of the 

application time is often spent executing loops. As a result, TRJIT employs many optimization techniques 

that are intended to aggressively improve loop performance in Java. You can assist the TRJIT compiler 

by using the following guidelines to ensure that their loops are well-behaved. 



Guideline: Do not modify the loop bounds within the loop body 

When the loop bounds are independent of the loop body, the TRJIT can usually profile the bounds 

and create specialized, more optimized versions of the loop. Furthermore, the ability to predict and 

compensate for loop exits is important for many fundamental loop optimization techniques, such as 

loop versioning and loop unrolling. If the loop bounds were modified within the loop body, such loop-

optimization techniques are typically not applicable, which results in poorer performance.  

 

IBM Just-In-Time Compiler (JIT) for Java 

Best practices and coding guidelines for improving performance 



 

 

 



 

Figure 10: Performance of Reflection example in Figure 9

 

Figure 11 shows an example of a poorly behaved loop with a loop bound ‘j’ that is modified within the 



loop.  

public void badLoopBounds() { 

 

int i = 0; 



 

while (i < j) { 

  ... 

 

 



j = newLoopBounds();  // Modifying of loop bounds  

  i++; 


 } 



Figure 11. Example of a poorly behaved loop bound - The loop bounds: j is modified within the loop by using the 



newLoopBounds() method 

 

 



 

IBM Just-In-Time Compiler (JIT) for Java 

Best practices and coding guidelines for improving performance 


 

 

 



Figure 12 shows a well-behaved version, where the loop bound is invariant. The JIT will be able to 

optimize the latter loop better. 

public void goodLoopBounds() { 

       int i = 0; 

 

while (i < N) { 



// Loop bounds N is never modified  

  ... 


  i++; 

 } 




Figure 12. Example of a well-behaved loop bound - The loop bound: N is never modified within the loop 

Guideline: Increment the loop index by a single value across all paths 

Similar to the previous guideline, many loop-optimization techniques depend on well-behaved loop 

iterations and the prediction of the number of iterations a loop will run. If two paths in the loop body 

increment the loop index by different amounts, many TRJIT loop-optimization techniques cannot be 

applied to improve the loop’s performance. 

Figure 13 shows a loop that increments the loop index by 1 or 2, depending on the condition of the 

nested if-statement. For the JIT compiler to optimize the loop, it must prove certain properties of the 

condition expression (for example, whether the condition expression is loop invariant), which might 

not be possible.  

public void badLoopIndexIncrements() { 

 

for (int i = 0; i < 100; i++) { 



 

 

// Loop Index may be incremented by 1 or 2  



  if 

(condition) 

 

   i++; 


  else 

 

 



 

i = i + 2; 

 

 





Figure 13. Example of poorly behaved loop-indices increments - The loop index: i will increment by 1 or 2, depending 

on the condition 

 

Figure 14 shows a well-behaved loop that only increments the loop index by a single value. The JIT 



recognizes this property and optimizes the loop accordingly. 

public void goodLoopIndexIncrement() { 

 

for (int i = 0; i < 100; i++) { 



 

 

// Loop index incremented by 1 all the time  



i++ 



Figure 14. Example of well-behaved loop-indices increments - The loop index: i will increment by the same value on 

each iteration 

IBM Just-In-Time Compiler (JIT) for Java 

Best practices and coding guidelines for improving performance 


Yüklə 153,14 Kb.

Dostları ilə paylaş:
1   2   3   4   5   6   7




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©genderi.org 2024
rəhbərliyinə müraciət

    Ana səhifə