1

I am new to Java.

At first, I was testing the performance on String and StringBuilder in different cases.

However, I discovered that same code compiled by javac and eclipse performed differently.

I read about that String concatenation is actually using StringBuilder but why is that performance has so big difference in this case while String is 1.5x faster than StringBuilder.

Here is my testing code:

public class StringTest { public StringTest() { boolean flag = true; int code = 10001, type = 1; long time = System.nanoTime(); for (int i = 0; i < 10000000; ++i) { String msg = Long.toString(i * 1000000000); stringHandler(code, type, flag, msg); } System.out.println("Took " + (System.nanoTime() - time) + " ns by String"); time = System.nanoTime(); for (int i = 0; i < 10000000; ++i) { String msg = Long.toString(i * 1000000000); stringBuilderHandler(code, type, flag, msg); } System.out.println("Took " + (System.nanoTime() - time) + " ns by StringBuilder"); } public String stringBuilderHandler(int code, int type, boolean flag, String msg) { StringBuilder sb = new StringBuilder(); sb.append("{\"bool\":").append(flag).append(",") .append("\"code\":").append(code).append(",") .append("\"type\":").append(type).append(msg).append("}"); return sb.toString(); } public String stringHandler(int code, int type, boolean flag, String msg) { String str = "{\"bool\":"; str += flag; str += ","; str += "\"code\":"; str += code; str += ","; str += "\"type\":"; str += type; str += msg; str += "}"; return str; } public static void main(String[] args) { StringTest st = new StringTest(); } } 

Using javac 1.8:

Took 1066623964 ns by String Took 1540007855 ns by StringBuilder 

Using Eclipse:

Took 4282720864 ns by String Took 1709934263 ns by StringBuilder 
5
  • 1
    You can decompile the code using javap -c and see what the bytecode looks like in both cases. Commented May 25, 2015 at 17:11
  • @Jesper Thanks for your advice. I noticed some differences that the bytecode compiled by eclipse invoked String.valueOf while javac didn't. But as I said, I am new to Java, I don't really understand how would this matters so much to the performance. I would be very thankful if you can give me further explanation. Commented May 25, 2015 at 17:33
  • do you use the same JVM to execute the code? which JVM? Commented May 25, 2015 at 18:39
  • @bayou.io Yes, it's the same, jre1.8.0_45 and I only have this environment in my os. Commented May 25, 2015 at 18:48
  • it won't be surprising if oracle's jvm optimizes better for oracle's javac output - not for nefarious reasons. jvm needs to look at the instruction pattern, guess what it does, and assume a strategy that's likely optimal. Commented May 25, 2015 at 19:59

1 Answer 1

4

There is a huge problem in your stringBuilderHandler and it's that you're creating a new instance of StringBuilder on every call, when you should reuse the same instance to see the concatenation. Do similar in stringHandler: reuse the same String variable, and then you will notice the difference. Also, you should follow the rules of a proper micro benchmark as shown here: How do I write a correct micro-benchmark in Java? or use a micro benchmark framework like Caliper or JMH.

Sign up to request clarification or add additional context in comments.

9 Comments

Yes, I am aware of the problem but I need to create the instance inside the method because I was implementing a handler which will be called by different threads and my fellow mentioned bad performance of StringBuffer declared outside the method. As I said, I am new to Java so I don't really know how to use those framework but I would like to try it. It's the different behaviors by this two make me so confused.
What's the use case you need to solve? Looks more like you need to append content to then print it into a file or something. I would use a BlockingQueue<String> rather than other synchronization techniques, and in the end empty the queue and concatenate its contents using StringBuilder once. Or maybe you only need a logging facility.
@ Luiggi Mendoza Thanks for your reply. Actually I am doing json transmission over network and I used Netty as my network framework.
I still don't understand where you need to synchronize the string manipulation. This should be designed to be done atomically. I guess you're mixing questions here. I suggest you to post a new question explaining your current use case, express your specific design issue and ask for guidance to solve that problem there. This question is about String concatenation and that's the scope of this answer as well.
The given code is just to test which one I should choose to use when I need to append string inside a method. Maybe it's a faulty design in network application? But my ultimate confusion here is the different behavior between eclipse and javac and it makes want to change my IDE because I found that NetBeans has no such problem.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.