Java Performance Tips 1

Java Performance Tips 1

9. Thread Synchronization

Synchronization is a concept used with threads where you want to give the method access exclusively to an object of a class. We must synchronize the data when other objects should wait until the accessing object completes its job. For example, when one object updates the data, the other object should not be allowed to modify the data. Synchronization is a very big overhead to the system and should be avoided generally. We must synchronize sensitive or critical data only.

In the following program, two methods, one synchronized and the other non-synchronized are called.

Calling synchronized method is 75 times overhead than non-synchronized method.

Java permits to synchronize a whole method or a block of a method.

Java permits to synchronize a part(block) of a method

Comparatively, the second style gives more performance.

This difference is important in some areas. The Vector and ArrayList works the same. Vector methods are synchronized, but ArrayList methods are not synchronized. For ordinary data, use ArrayList in place of Vector.

10. Java Performance Tips: Inner classes

A class declared in another class is called nested class or inner class. As the specification says, the inner class can access the private data of outer class. But it is against the rules of Java; one call private properties cannot be accessed by other classes.

In the following program, OuterOne is outer class and the InnerOne is inner class. The private method calculate() of outer class is accessed by inner class constructor. Let us see the code and then we will discuss how Java executes the code of private property of outer class by inner class.

InnerOne is enclosed within OuterOne. calculate() method is defined within OuterOne. Because the Java Virtual Machine has restrictions on calling private members from outside of their class, a special access method is generated by the compiler and added internally to the OuterOne class. This method has a name access$0(), and it in turns calls calculate(). In other words, a method is generated that can be called from outside of InnerOne, and grant access to a private method of OuterOne. So when calculate() is called, the above generated method access$0() is called, and it in turn calls calculate(). So use inner classes, that too access the private data of the outer, only when the code demands.

11. String and StringBuffer

String is designed to be immutable. A string is a sequence of Unicode characters and represented by an object of String class(no terminating \0). Immutable means once created, they never change. If you reassign a new value, the new value is stored in a new location and the new location reference is stored in the String object and the old value is garbage collected. This increases a lot of overhead and should be avoided. If a string value is to be changed, the programmer should prefer StringBuffer which is mutable.

String str = “Hello”;
str = str + “World”;

the string "Hello", once created, does not change, but a reference to the string (value) may change. The string reference in str originally points to "Hello", but then is changed to point to a new string formed by concatenating str and "World". The above sequence is implemented internally using code like:

String str = “Hello”;
StringBuffer sb = new StringBuffer(str);
str = sb.toString();

In other words, the two strings to be concatenated are copied to a temporary string buffer, then copied back. As it is clear, such concatenation a big overhead. We should not use + and += with strings.

String concatenation, nearly 2500 times, makes the process to run slower than using StringBuffer.

11.1 Accumulating data Using char[] Arrays

To concatenate characters, there is a better and effective way than using a StringBuffer. We place the data in a character array and then converting the array into a string.

The time taken for the above is very negligible and most probably below 1 millisecond.

11.2 Using == and equals() with Strings

The logical operator, in case of strings, compare whether both the string objects refer to the same location or not whereas equals() method compares whether both strings contain the same characters or not, but not their locations. It is a little bit confusing concept for a novice.

Using == is less expensive (overhead) than using equals() method. To increase the performance, it is better to check first with == and then equals(). If == turns to true, then equals() method is short-circuited(not executed) which sometimes works out.

11.3 Using the length() of a String

Using length() method of a String once or while in a program is not a big botheration. But used in a loop, a number times, may decrease the performance.

Using length() method is more expensive than using a precomputed value. Avoid using length() in a tight loop.

11.4 Using toCharArray()

charAt() is a String method similar to length(), which can be expensive if called for every character in a long string. An alternative to this method is use of toCharArray(), which returns a copy of the string in a char[] array fashion.

In other words, converting the characters of a string into a char[] array eliminates the method call overhead of charAt(). But char[] array takes more space. Moreover, length() method of String is more expensive than length variable of an array. First uses a method call and the later uses a runtime descriptor.

11.5 Converting strings and double to Wrapper objects

Suppose you have a string like "35.19" that represents a number, and you’d like to convert it to numeric form. How expensive is such an operation? One way to find out is by writing a small program that creates a Double (a wrapper class for double), from either a string or a number.

Constructing a Double from a string value is 60 times expensive to a double value.

5 thoughts on “Java Performance Tips 1

Leave a Reply

Your email address will not be published. Required fields are marked *