Java performance best practices for developers:
1. Finalize:
2. Synchronized Block
3. isThreadsafe
{
private String baz() {
String bar = "howdy";
return bar.toString();
}
}
Use StringBuffer.length() to determine StringBuffer length rather than using StringBuffer.toString().equals("") or StringBuffer.toString().length() ==. Example:
public class Test {
void bar() {
StringBuffer sb = new StringBuffer();
// this is bad
if(sb.toString().equals("")) {}
// this is good
If(sb.length() == 0) {}
}
}
Best Example:
public class Main {
public static void main(String[] args) {
long now = System.currentTimeMillis();
slow();
System.out.println("slow elapsed " + (System.currentTimeMillis() - now) + " ms");
now = System.currentTimeMillis();
fast();
System.out.println("fast elapsed " + (System.currentTimeMillis() - now) + " ms");
}
private static void fast() {
StringBuilder s = new StringBuilder();
for(int i=0;i<10000;i++)
s.append("*");
}
private static void slow() {
String s = "";
for(int i=0;i<10000;i++)
s+="*";
}
}
Output is:
slow elapsed 11741 ms
fast elapsed 7 ms
The problem is that to += append to a string reconstructs a new string, so it costs something linear to the length of your strings (sum of both).
10.SingleThreadModel:
1. Format
2. MessageFormat
3. NumberFormat
4. DecimalFormat
5. ChoiceFormat
6. DateFormat
7. SimpleDateFormat
Joda Time, a complete replacement for Java's date and time API. It overcomes many of the deficiencies in Java's date API, while still remaining compatible with it. Additionally, there is a good chance that Joda Time will form part of Java SE 7. So by downloading and using Joda Time now, you'll be going the way of the Java future. The cost of using Joda is that conceptually it is somewhat different from the current Java date libraries, which at first may slow you down. Additionally you'll need to add the Joda Time jar to your project.
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
1. Finalize:
- Avoid implementing a Finalize method. The garbage collector must promote finalizable objects to older generations to facilitate finalization, which makes them long-lived objects.
- Avoid having finalizable objects refer to anything. This can cause the referenced object(s) to become long-lived.
- Adding finalizers to code makes the garbage collector more expensive and unpredictable. Objects with finalizers have significant overhead compared to objects without finalizers, and should be used sparingly. Finalizeable objects are both slower to allocate and slower to collect. At allocation time, the JVM must register any finalizeable objects with the garbage collector, and finalizeable objects must follow a slower allocation path than most other objects. Similarly, finalizeable objects are slower to collect, too. It takes at least two garbage collection cycles (in the best case) before a finalizeable object can be reclaimed, and the garbage collector has to do extra work to invoke the finalizer. The result is more time spent allocating and collecting objects and more pressure on the garbage collector, because the memory used by unreachable finalizeable objects is retained longer.
2. Synchronized Block
- Using synchronized blocks in code, will increase the response time in multithreaded application.
- Many performance studies have shown a high performance cost in using synchronization in Java. Improper synchronization can also cause a deadlock, which can result in complete loss of service. But performance overhead cost is not a sufficient reason to avoid synchronization completely. Failing to make sure your application is thread-safe in a multithreaded environment can cause data corruption, which can be much worse than losing performance. It should be used optimistically where ever it is required.
3. isThreadsafe
- Do not use isThreadSafe="false" if you want multithread support. Make your JSPs thread-safe if possible.
- Using isThreadSafe=”false” attribute in the JSP’s, after translation process in to servlet, will implement SingleThreadedModel interface.
- It should be called only once per class. If required for the next iteration do new Class () and cache it in a static hash map. For the next iterations retrieve the instance from the hash map.
- It returns same instance object for any number of requests. The Singleton database access class means that there will be only 1 instance shared by all threads. In a multi-threaded application, the method is synchronized. When the load is high, the method becomes the bottleneck for performance
- toString() concatenations and string concatenations is a performance bottleneck. So StringBuffer or StringBuilder should be used instead of toString. Removing toSring() calls in the debug statements improves the scalability. Usage of StringBuffer instead of String concatenation will improve the TPS.
Avoid calling toString() on String objects; this is unnecessary.
Example:
{
private String baz() {
String bar = "howdy";
return bar.toString();
}
}
Use StringBuffer.length() to determine StringBuffer length rather than using StringBuffer.toString().equals("") or StringBuffer.toString().length() ==. Example:
public class Test {
void bar() {
StringBuffer sb = new StringBuffer();
// this is bad
if(sb.toString().equals("")) {}
// this is good
If(sb.length() == 0) {}
}
}
Best Example:
public class Main {
public static void main(String[] args) {
long now = System.currentTimeMillis();
slow();
System.out.println("slow elapsed " + (System.currentTimeMillis() - now) + " ms");
now = System.currentTimeMillis();
fast();
System.out.println("fast elapsed " + (System.currentTimeMillis() - now) + " ms");
}
private static void fast() {
StringBuilder s = new StringBuilder();
for(int i=0;i<10000;i++)
s.append("*");
}
private static void slow() {
String s = "";
for(int i=0;i<10000;i++)
s+="*";
}
}
Output is:
slow elapsed 11741 ms
fast elapsed 7 ms
The problem is that to += append to a string reconstructs a new string, so it costs something linear to the length of your strings (sum of both).
- Usage of StringBuffer or StringBuilder instead of String concatenation will improve the TPS.
- Hashtable and Vector are inherently threadsafe. It means writes and reads will happen serially. Hence, in a multithreaded environment all other threads will wait for a common resource. Then that resource will act as bottle neck.
- ServletRequest.getRemoteHost() is very inefficient, and can take seconds to complete, the reverse DNS lookup it performs.
- OutputStream can be faster than PrintWriter. JSPs are only generally slower than servlets when returning binary data, since JSPs always use a PrintWriter, whereas servlets can take advantage of a faster OutputStream.
10.SingleThreadModel:
- Do not use javax.servlet.SingleThreadModel.
1. Format
2. MessageFormat
3. NumberFormat
4. DecimalFormat
5. ChoiceFormat
6. DateFormat
7. SimpleDateFormat
Joda Time, a complete replacement for Java's date and time API. It overcomes many of the deficiencies in Java's date API, while still remaining compatible with it. Additionally, there is a good chance that Joda Time will form part of Java SE 7. So by downloading and using Joda Time now, you'll be going the way of the Java future. The cost of using Joda is that conceptually it is somewhat different from the current Java date libraries, which at first may slow you down. Additionally you'll need to add the Joda Time jar to your project.
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;