String concatenation into StringBuilder java

2020-02-29 12:16发布

I have a legacy Java file which uses String concatenation to build huge String objects.Its a serious performance issue.Is there a method as such which does the following

String test="I am a very bad programmer"
+"to use concatenation"
+"Instead of StringBuilder"
+" or StringBuffer";

to

StringBuilder strBuilder= new StringBuilder();
strBuilder.append("I am a bad programmer");
strBuilder.append("to use concatenation");
strBuilder.append("Instead of StringBuilder");
strBuilder.append(" or StringBuffer");
String str= strBuilder.toString();

basically I need a stub in java just to give a the String instantiation as input and convert into StringBuilder.Anybody tried this in the past?

4条回答
可以哭但决不认输i
2楼-- · 2020-02-29 12:53

Just constant string contatenation is optimised at compile time, and is trivial. The issue is when you do something less trivial:

String example1 = "Prefix" + variableString1 + "Suffix";

the worst case is loops with appending where every iteration needs to create a new string. Since this is common for buffered reads of files you can get very big strings being recreated, a problem I had recently.

While I see why you'd want to do what you do, the structures of the code are too different to just drop in and replace, and a script to edit the code would have to be quite advanced to be able to deal with all the references. Maybe there is a way with annonomous inner classes though that can let you keep the same string reference but wrap the actual construction in string builders. It's probably no different than what the optimiser already does though

查看更多
家丑人穷心不美
3楼-- · 2020-02-29 12:56

A fixed literal like in your example is more efficient than using a StringBuilder.

The fixed literal will be detected by the compiler and will be inlined as a single value, so the two lines

String s = "one" + "two" + "three";

and

String s = "onetwothree";

will generate exactly the same bytecode.

The picture is different though if the concatenation is not done with literals but with function calls.

When you need to append strings dynamically, prefer StringBuilder over StringBuffer because it is slightly faster as it is not synchronized.

Here is the example bytecode:

public class Test
{
   private String s = "one" + "two" + "three";
}

public class Test2
{
   private String s2 = "onetwothree";
}

the generated bytecode for these classes is:

c:\Temp>javap -c Test
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   aload_0
   5:   ldc     #2; //String onetwothree
   7:   putfield        #3; //Field s:Ljava/lang/String;
   10:  return
}
c:\Temp>javap -c Test2
Compiled from "Test2.java"
public class Test2 extends java.lang.Object{
public Test2();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   aload_0
   5:   ldc     #2; //String onetwothree
   7:   putfield        #3; //Field s:Ljava/lang/String;
   10:  return
}

As you can see both variables are treated the same way.

I don't think this belongs to the language specification, as this is "just" a compiler optimization.

A different compiler (I was using the Sun compiler) might be doing something completely different - which is OK as long as the behaviour doesn't change.

查看更多
Animai°情兽
4楼-- · 2020-02-29 12:57

No, it isn't a performance issue. If you are concatenating the string inline (just like you showed) rather than using a loop for example, then the compiler automatically transforms the + to using a StringBuilder. Check the documentation of java.lang.String

The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method. String conversions are implemented through the method toString, defined by Object and inherited by all classes in Java. For additional information on string concatenation and conversion, see Gosling, Joy, and Steele, The Java Language Specification.

Even further - the compiler may use the fact that these are all string constants and join them even before runtime (JLS references)

查看更多
Anthone
5楼-- · 2020-02-29 12:58

Actually the compiler already applies that optimization for you in the latest versions of Java (at least from 1.5, I think).

What happens when Java Compiler sees many String concatenations in one line?

http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.18.1.2

查看更多
登录 后发表回答