Har*_*ish 2 java performance stringbuilder concatenation
我有一个遗留Java文件,它使用字符串连接来构建巨大的String对象.这是一个严重的性能问题.是否存在这样的方法,它执行以下操作
String test="I am a very bad programmer"
+"to use concatenation"
+"Instead of StringBuilder"
+" or StringBuffer";
Run Code Online (Sandbox Code Playgroud)
至
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();
Run Code Online (Sandbox Code Playgroud)
基本上我需要一个java中的存根只是为了给一个String实例化作为输入并转换成StringBuilder.Anybody过去试过这个?
Boz*_*zho 13
不,这不是性能问题.如果您将字符串内联(就像您显示的那样)而不是使用循环,那么编译器会自动将其转换+为使用a StringBuilder.查看文档java.lang.String
Java语言为字符串连接运算符(+)提供特殊支持,并为其他对象转换为字符串.字符串连接是通过StringBuilder(或StringBuffer)类及其append方法实现的.字符串转换是通过方法toString实现的,由Object定义并由Java中的所有类继承.有关字符串连接和转换的其他信息,请参阅Gosling,Joy和Steele,Java语言规范.
更进一步 - 编译器可能会使用这些都是字符串常量并在运行时(JLS 引用)之前连接它们的事实
像示例中的固定文字比使用StringBuilder更有效.
固定文字将由编译器检测,并将内联为单个值,因此两行
String s = "one" + "two" + "three";
Run Code Online (Sandbox Code Playgroud)
和
String s = "onetwothree";
Run Code Online (Sandbox Code Playgroud)
将生成完全相同的字节码.
如果连接不是使用文字而是使用函数调用,则图片是不同的.
当你需要动态追加字符串时,首选StringBuilder而不是StringBuffer,因为它不会同步,因为它稍快一些.
这是示例字节码:
public class Test
{
private String s = "one" + "two" + "three";
}
public class Test2
{
private String s2 = "onetwothree";
}
这些类的生成字节码是:
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
}
正如您所看到的,两个变量的处理方式相同.
我不认为这属于语言规范,因为这只是"编译器优化".
一个不同的编译器(我使用的是Sun编译器)可能会做一些完全不同的事情 - 只要行为没有改变就可以了.