Java Performance Tips 1


 1.  Introduction
 2.  When to think of Performance
 3.  JVM’s and JIT Compilers
 4.  Default constructors
 5.  Constructor Hierarchies
 6.  Instance variables Vs Class(static) variables
 7.  Recycling Objects
 8.  Methods
     8.1  Inlining Methods
     8.2  Final Methods
 9.  Thread Synchronization
10. Inner classes
11. String and StringBuffer
    11.1  Accumulating data Using char[] Arrays
    11.2  Using = = and equals() with Strings
    11.3  Using the length() of a String
    11.4  Using toCharArray()
    11.5  Converting strings and double to Wrapper objects
12. I/O Streams
    12.1  Using Chaining
13. Formatting
14. Getting File Information(Disk access)
15. Libraries
    15.1  java.util package
    15.2  Vector vs. ArrayList
    15.3  Setting Initial Array Capacity
    15.4  Setting Initial Array Capacity
    15.4  ArrayList vs. LinkedList
16. Programming in Terms of Interfaces
17. Wrappers
18. Garbage Collection
1. Java Performance Tips: Introduction

Performance has been an important issue for Java developers with any language. Performance includes both speed of execution and the memory, the process, occupies. That is, how to make our program run faster and at the same time using less memory and disk space. There is no correct formula on performance because different applications have different characteristics and bottlenecks and also performance differs across different hardware, operating systems and development tools like virtual machines and compilers. This training provides how tricks such as minimizing object creation and replacing strings with arrays can really pay off in improving your code’s performance. The aim of the two days discussion is to promote the awareness of performance issues in Java so that we can make suitable design and implementation options for specific tasks. Java Performance Tuning offers common-sense advice about what to tune and what to leave alone, emphasizing techniques that provide big performance gains with minimal code

2. Java Performance Tips: When to think of Performance

Programmer should bother not only the performance but also should consider the issues like quality, readability and maintainability etc. Some techniques may ultimately lead to more complex code and should be considered only when required. Sometimes, the performance issues must be considered at design phase itself. If poor performance is built into the architecture itself, it becomes very difficult to tune the performance. For example, choosing an N*N sort of algorithm instead of more efficient N*log(N) one and using many super classes(subclass constructor invokes all its super class constructors) is a bad design. Suppose the code is designed to read the data in a number of chunks and is chunk is processed by many constructors of the super classes and such code requires complete redesign which becomes practically very difficult and time consuming. For this reason, it is important to keep in mind, the performance issues in the design phase itself.

3. Java Performance Tips: JVM’s and JIT Compilers

The latest versions of Java tools offer various approaches to increase performance compared to the original JDK1.0 version of byte code interpretation. The tools approaches includes compiling(interpretation stage) the bytecode into machine code at runtime. Some areas where performance enhancement can be done include a) method inlining and adaptive inlining where methods are inlined basing on their use and number of calls b) synchronization c) compiling Java source code into native code of the operating system etc. As a designer, examining and choosing of appropriate tools is also important. Using a JVM with built-in JIT compiler increases the performance 40 times. Choosing the right tool is very important rather than trying to tune the code for performance aspects.

A small Clock program developed to know the performance:

public class Clock 
{
  long time;
  public Clock() 
  {
    setZero();
  }
  public void setZero() 
  {
    time = System.currentTimeMillis();
  }
  public long timeTaken() 
  {
    return System.currentTimeMillis() - time;
  }
  public void printTime(String str) 
  {
    System.out.println(str + ": " + timeTaken());
  }
  public static void main(String args[])
  {
    Clock c1 = new Clock();
    for(int i = 0; i < 1000000; i++) { }
    c1.printTime("Time tiken for 1000000 iterations");
    c1.setZero();
    
    for(int i = 0; i < 100000000; i++) { }
    c1.printTime("Time tiken for 100000000 iterations");
  }
}

Java Performance Tips

The above screen shows different results when executed different times. It is because a number processes may be running right now on your system, some of which may be in pause, working or stopped etc. Also it depends on the availability of JVM free time. The above Clock program is used in every program to know the performance.

4. Java Performance Tips: Default constructors

Observe the code:

public class Demo
{
  public static void main(String args[])
  {
    Demo d1 = new Demo();
  }
}

In the above code, we created an object of Demo class, d1, by accessing the default constructor; but the default constructor is not provided by the programmer. If the programmer does not provide his own default constructor, the JVM creates one and supplies and this takes time. So, always provide a default constructor in your program.

5. Java Performance Tips: Constructor Hierarchies

Suppose we have the following class hierarchy:

class A {...}
class B extends A {...}
class C extends B {...}

As discussed above, when we create an object of class C, its default constructor calls the default constructors of all super classes up to class Object. This takes some time. For this reason, involve less super classes in the hierarchy.

6. Java Performance Tips: Instance variables Vs Class(static) variables

When the data is the same used by all the objects of the class, better declare the variables as static. Static variables are initialized only once. By declaring non-static, we must assign the value for each object separately which is time consuming and takes more space. The difference makes a lot as the following program explains:

public class StaticVsInstance
{
  int rno;   	 	                  // declare static 
  String name;      	                  // declare static and see the difference
  public void call()
  {
    rno = 35;
    name = "S N Rao";
  }
  public static void main(String args[])
  {
    StaticVsInstance svi[]  = new StaticVsInstance[200000];
    Clock c1 = new Clock();
    for(int i = 0; i < 200000; i++)
    {
      svi[i] = new StaticVsInstance();
      svi[i].call();
    } 
    c1.printTime("Non-static variables");   
  }
} 

If the variables are not static, 2,00,000 objects will have their own memory locations for rno and name. If static, only one memory location is created and shared by all 2,00,000 objects of the class.

7. Java Performance Tips: Recycling Objects

Instead of creating a number of objects for a single class, if an object job is over, the same object can be reused a number of times as follows:

Demo d1 = new Demo(); // create an object initially

If the job of d1 is over:

d1 = null; // this is, in fact, not required
d1 = new Demo();

Now the object d1 can be used for new data.

8. Methods

There exists an inherent overhead associated with calling methods. These overheads includes actual transfer of control to the called method, parameters passing, return value return to the calling method and establishment of the called method’s stack frame for local variable storage. This type of overheads exists in other programming languages also.

8.1 Java Performance Tips: Inlining Methods

The most efficient style to deal with method call overhead is method inlining. The method inlining can be done by the programmer or a compiler also implicitly. Inlining is nothing but writing the called method code in the calling method itself. Observe the following example:

			// Not Inline code

public class MethodInlining
{
  public int getMaximum(int a, int b)
  {
    return (a > b ? a : b);
  }
  public static void main(String args[])
  {
    MethodInlining mi = new MethodInlining();
    Clock c1 = new Clock();
    for( int i = 0; i < 10000000; i++)
    {
      int c = mi.getMaximum(10,20);
    }
    c1.printTime("Not Inline");   
  }      
}

Now shift the Inline code. Shift the calling method code into the calling method main itself.

                          // Inline code
public class MethodInlining
{
  public static void main(String args[])
  {
    MethodInlining mi = new MethodInlining();
    Clock c1 = new Clock();
    int a = 10, b = 20;
    for( int i = 0; i < 10000000; i++)
    {
      int c = a > b ? a : b;
    }
    c1.printTime("Inline");   
  }
}

With inline code, the performance is improved 2 to 3 times.

8.2 Java Performance Tips: Final Methods

The compiler places final methods as inline methods because subclass methods need not be called. Final methods cannot be overridden by subclass.

public final display() { }

The same style can be applied to classes also by declaring them final. A final class cannot be inherited and thereby all the methods of a final class are implicitly final.

public final class Demo { }

If a subclass method is assigned to a super class, the super class will call subclass overridden method. If the class is not declared as final, the JRE has to check its subclasses whether the super class method is overridden or not. If overridden, it must call the subclass method. For the dynamic method dispatch, it takes a long time and is a overhead. It is very difficult to inline subclass methods as which subclass method is to be called is decided at runtime. So, when the code does not include method overriding, simply declare the super class method as final and also when you do not extend your class, declare it as final.

5 thoughts on “Java Performance Tips 1”

Leave a Comment

Your email address will not be published.