Search This Blog

Sunday, May 13, 2012

Java Performance Tips 1 - String Operations


String Operations
There are some performance tips for String manipulation in java, one of them is the concatenation operation.
Concatenation operation can be done by appending the values on the same String object for example:
String str = new String ();
String s = "test";
str+=s;
str+="testString";
The compiler translated this simple line to the following J
str = (new StringBuffer()).append(s).append("testString").toString();
But this method is not preferable (as we will know later), one other method is using StringBuffer .


Using StringBuffer Method
StringBuffer is used to store character strings that will be changed as we know that String class is immutable, so we can concatenate the strings as follows:
StringBuffer sbuffer = new StringBuffer();
sbuffer.append("testString");

StringBuffer vs StringBuilder
Also there is another method to concatenate the String using StringBuilder which is introduced in Java 5, StringBuilder is like the StringBuffer except it is not synchronized, which means that if there are many threads, they can change it in the same time (StringBuilder is not suitable in the multithreading applications).
'Ok, why this stuff for, just for concatenate some strings!' you may ask this question, after running a sample of each and profiling the performance.

Code Example

public class StringOperations {
    public void concatenateUsingString() {
        String str = new String();
        for (int i = 0; i < 10000; i++) {
            str += "testString";
        }
    }
    public void concatenateUsingStringBuffer() {
        StringBuffer sbuffer = new StringBuffer();
        for (int i = 0; i < 10000; i++) {
            sbuffer.append("testString");
        }
    }
    public void concatenateUsingStringBuilder() {
        StringBuilder sbuilder = new StringBuilder();
        for (int i = 0; i < 10000; i++) {
            sbuilder.append("testString");
        }
    }
}

And in the main method, a simple calling to the three methods

public static void main(String[] args) {
        StringOperations soperations = new StringOperations();        
        soperations.concatenateUsingString();
        soperations.concatenateUsingStringBuffer();
        soperations.concatenateUsingStringBuilder();
    }


The result is like the following:
The Results by seconds







The Results by percentage









I have used the Eclipse Test & Performance Tools Platform Project (TPTP) to validate the results, just right click on the project and choose 'Profile As'.

Profile As













Then choose 'ProfileàProfile Configuration '


Profile Configuration


















This result shows the big performance issue of using the String concatenation (Plus operation),
the profiler tells us that the calling of concatenateUsingStringBuffer and concatenateUsingStringBuilder (approximately 0.08%) of time are nothing with respect to concatenateUsingString (99.85% of time).
    http://www.javaworld.com/javaworld/jw-03-2000/jw-0324-javaperf.html
    http://leepoint.net/notes-java/data/strings/23stringbufferetc.html




8 comments:

  1. Assalamu alikum Yahya,

    Nice effort! However, I have some comments, if you'd allow me:
    1) The compiler's translation does not map to the code shown.
    2) `StringBuilder` *is* suitable for multi-threaded applications, as long as you use it locally or in a thread-safe object. A local variable is guaranteed to be thread safe by definition.
    3) The articles you used as references are too old by now. Try looking for newer articles :)

    ReplyDelete
  2. Wa Alykom al Salam Hossam,

    Thanks a lot for your fruitful comments, actually I have written these articles from 2 or 3 years :) and I shared it internally in my company. When looking to my stuff, I decided to copy and paste it now in a new post :) thanks again for your comments :)

    ReplyDelete
  3. I will post in near future my experience in Large Scale programming models like Hadoop, HBase ... Stay tuned :)

    ReplyDelete
  4. About the compilation, check this link http://stackoverflow.com/questions/7663252/java-string-concat-in-stringbuilder-call

    ReplyDelete
  5. I'm not saying that the compiler's translation is incorrect; it just doesn't map to the code you wrote. Just read your first paragraph. Even variable names and values don't match! It seems like it has been copied from elsewhere, without adjusting the values.

    ReplyDelete
  6. Yes got you ... I have updated the HTML .. Thanks Hossam :)

    ReplyDelete