8 Performance Tuning Tips in Java

8 Performance Tuning Tips in Java:

Before start doing performance tuning/optimizations, first use any profiler to identify the areas for optimizations using profilers

 

Few Java Profilers:

yourkit
jProfiler
Java Flight Recorder
Eclipse Test & Performance Tools Platform Project

 

1. Use available data structures or algorithms:

If you want to convert list to set or vice versa, instead of iterating a list/set to copy the values to list/set, you can use the inbuilt method addAll().

So always check for an inbuilt functionality before writing your own code to achieve your functionality.

 

2. Logger Vs System.out.println():

Logger: to print the output/warning/errors/debug texts in the file.

Sysout: prints everything in the console.

Logger is faster than sysout and also has an option to configure for different levels. So for better performance remove all the sysouts and put loggers whereever it is needed and applicable.

 

3. Primitive vs Wrapper Class ?

If you have a value 5 and need to be assigned to any variable, then considering that variable as int(primitive data type) or wrapper class(Integer) may give you little impact on the performance.

Primitive data types are simple and faster.

Wrapper classes can be used when you want to do any extra functionalities(like converting integer to string), then Integer wrapper class can be prefered. Also remember collections will allow wrapper or boxed primitives only.

Note: As per the profiling it’s not really creating much performance impact, but still it can also be considered for performance tuning.

 

4. String vs StringBuilder

whenever a string concatenations need to be done use mutable objects such as stringbuilder/stringbuffer rather than + concatenation operator.

Use Mutable objects:

Instead of creating multiple objects all the time(String calls empty constructor all the time and creates a new object), if you use mutable objects it will not create new objects all the time, it will change the same object, which help us to save the time.

Since in string new string need to be created on each appending/concatinating, where as in stringbuilder/StringBuilder we can change directly in that itself. So it’s highly recommended to use StringBuilder on appending/concating with in the loops.

For eg:

Loop Appending Using String: If you execute this loop, it takes around 200 milli seconds:


String s = "0";
for(int i = 1;i<10000;i++){
s = s+i;
}

 

Loop Appending Using StringBuilder/StringBuffer: It just takes less than 5 milli seconds.


StringBuilder s = new StringBuilder("0");
for (int i = 1; i < 10000; i++) {
s.append(i);
}

 

Remember: String immutability really provides lot of advantages over mutablity but it fails to perform only when appending/concatenating within the loop.

Note: If String used with the objects containing lots of data, memory consumption can become an issue.

 

5. Avoid synchronization when not needed:

StringBuilder vs StringBuffer:

StringBuffer: It takes min 23 milli seconds


StringBuffer s = new StringBuffer("0");
for (int i = 1; i < 1000000; i++) {
s.append("");
}

 

StringBuilder: It takes max of 10 milli seconds


StringBuilder s = new StringBuilder("0");
for (int i = 1; i < 1000000; i++) {
s.append("");
}

 

Both executes same number of time, since stringbuffer is thread safe, it takes extra time to complete it’s execution on synchronization.

6. Prefer for loop/for each/while loop rather than iterator:

Since iterator is creating iterator newinstance(), for loopings always prefer for each/for loops/while loops.

Loop performance testing by mkyong

 

7. Assign once and use multiple times/places:

Change the below code block appropriately:

Before refactoring:


if (getMobilesList() != null) {
for (Mobiles mobile : getMobilesList()) {

}
}

 

Here getMobilesList() is used for both null check and for for each iteration. If this method has very simple logics/implementations then performance will be unnoticable/ignorable.

If getMobilesList() has very complex logics then calling it in two places will execute the same complext logics twice and affect the performance surely.

 

That case, refactoring the above code like below will really help for good performance,

After refactoring:


List mobilesLst = getMobilesList();

if (mobilesLst != null) {
for (Mobiles mobile : mobilesLst ) {

}
}

 

Here getMobilesList() executed only once and the same is referenced with mobilesLst. So using mobilesLst twice/thrice/more than that will not have any performance impact, since it executed only once.

 

8. Consider Best Big(O) Notation Algorithms or logics:

This is the one which needs to be understood very deeply to implement properly, to explain you I will take a below scenario:

Now you have a list with 1,00,000 sorted elements and need to write a searching algorithm to get the given element position, now you can either write linear searching algorithm or binary searching algorithm for this scenario.

But linear has the big o notation of O(n) and binary has the big o notation of just O(log n) which means for 100 elements linear searching algorithm may take 100 iterations at worst case, where as binary searching algorithm takes only 6 to 7 iterations even in worst case for any of the given element to be searched.

Binary Search Implementation in Java Example
All Algorithms with Java Example:

 

Few mostly required and used performance tunings are shared above. You can go through the complete java performance tuning tips in the below link,

Java Performance Guidelines from IBM

Note: Always keep upgrading your jdk. Because lot of performance improvements will be included in the upgraded version.

1,088 total views, 3 views today

About: Mirthbees

Blogger, Innovator, Developer and Enterpreneur. Founder of GuruRecharge, Readymade online recharge script. Lead Developer in Bookrate.in