Wednesday, April 6, 2011

Tuneup Your Java Code


Performance tuning is a major concern while writing any mission critical application as well as multi-threaded application.
There are several factors that affect the performance like
1)      Performance of application decreases as the amount of memory consumption increases and memory unable to cleanup by the GC (Garbage Collector).  GC cleans the memory if and only if there is no live incoming and outgoing reference to the object.
2)      Avoid declaration of unwanted local variable which occupies stack memory during function call.
3)      Based on operation prefer appropriate data types …each data type holds different amount of memory.
4)      If class creating any connection object with the database and running long transaction then performance tuning is directly proportional to reduction of transaction lock period.
5)      Reduce unwanted debug statements from your code which will cases I/O call to write the log into the disk.
6)      It is import but not obvious to writes small and meaningful debug statements to reduce size of I/O call.
To avoid the performance issue we can have proper knowledge what we have to used and when.  Consider simple string concatenation function to concatenate a string 1, 00,000 times.
Code snippet 1:
/**
 * StringTest.java
 * Created on April 5, 2011
 */

package com.performance.test;

/**
 * @author Ashish.Chudasama
 * @version $Revision$ Last changed by $Author$ on $Date$ as $Revision$
 */
public class StringTest
{
    public static void main(String[] args)
    {
        long startTime = System.currentTimeMillis();
        String str = new String();
        // Amount of time required to execute the append operation
        for (int i = 0; i < 100000; i++)
        {
            str = str + (i);
        }
        //System.out.println(str.toString());
        long endTime = System.currentTimeMillis();
        System.out.println("Time Consume : " + (endTime - startTime)+ "ms");
    }

}
Output :
Time Consume : 551172ms
/**
 * StringBuilderTest.java
 * Created on April 5, 2011
 */

package com.performance.test;

/**
 * @author Ashish.Chudasama
 * @version $Revision$ Last changed by $Author$ on $Date$ as $Revision$
 */
public class StringBuilderTest
{

    public static void main(String[] args)
    {
        long startTime = System.currentTimeMillis();
        StringBuilder strBuilder = new StringBuilder();
        // Amount of time required to execute the append operation
        // This code is obtain by decompiling the StringBuilder class
  // public StringBuilder append(char paramChar)
        // {
        // super.append(paramChar);
        // return this;
        // }
        for (int i = 0; i < 100000; i++)
        {
            strBuilder.append(i);
        }
       // System.out.println(strBuilder.toString());
        long endTime = System.currentTimeMillis();
System.out.println("Time Consume by StringBuilder : " + (endTime - startTime)+ "ms");
    }

}

Time Consume by StringBuilder : 114ms

/**
 * StringBufferTest.java
 * Created on April 5, 2011
 */

package com.performance.test;

/**
 * @author Ashish.Chudasama
 * @version $Revision$ Last changed by $Author$ on $Date$ as $Revision$
 */
public class StringBufferTest
{

    public static void main(String[] args)
    {
        long startTime = System.currentTimeMillis();
        StringBuffer strBuffer = new StringBuffer();
        // Amount of time required to execute the append operation
        // This code is obtain by decompiling the StringBuffer class
        // public synchronized StringBuffer append(char paramChar)
        // {
        // super.append(paramChar);
        // return this;
        // }
        for (int i = 0; i < 100000; i++)
        {
            strBuffer.append(i);
        }
        //System.out.println(strBuffer.toString());
        long endTime = System.currentTimeMillis();
System.out.println("Time Consume by StringBuffer : " + (endTime - startTime)+"ms");
    }

}

Output :
Time Consume by StringBuffer : 277ms

This simple example shows that amount of time consume to perform same operation on different implementation of string.
Depth analysis of the overhead associated with each string implementation is as follow


String
StringBuffer
StringBuilder
Type
Immutable
Mutable
Mutable
Operation Synchronized  
No
Yes
No
Mutual exclusion is enforced by the monitor class for the string operations?
No
Yes
Yes
String Pool concept is used to generate the string and allocate the new string
Yes
No
No
Same memory buffer used for the all string operation
Every time new instance is created
All operation perform on same memory buffer
All operation perform on same memory buffer
Thread synchronization required explicitly?
Yes ,With the help if synchronize block mutex is enforce explicitly by the programmer
No ,By default all methods marked as synchronized
Yes ,With the help if synchronize block mutex is enforce explicitly by the programmer
Time consumed to concatenate string 1,00,000 times (this time may change during each execution but remains almost same)
Time Consume : 551172
Time Consume by StringBuffer : 277ms

Time Consume by StringBuilder : 114ms


This small example demonstrate if you used String class instated of stringBuffer and StringBuilder then performance has direct impact on overall task executed by the such code.
Try to explain more such code and concept on forthcoming post…

1 comment:

  1. Good article yaar...very useful. I got certain useful things from this.
    Object is very precious thing like money so use it carefully.
    We lost the money once we used, but objects can be reuse, recycle. Netbeans Profiler is very useful tool to check the run-time behavior of an application.

    ReplyDelete