我认为就两个字符串的拼接来说+的性能完全等于StringBuilder(1.5)/StringBuffer(1.4)

crowgns 2010-02-01 02:03:00
jvm在处理字符串拼接符号+时,是用StringBuilder(jdk>=1.5)/StringBuffer(jdk<=1.4)实现的。网上常见的是不要用+号要用StringBuilder的观点 ,理由是认为下面这段代码有性能差异:

String st1 = "hello" + "world";

StringBuild sb = new StringBuilder("hello");
sb.append("world");
String st2 =Sb.toString();

网上的观点认为,用加号的虽然用了StringBuilder来实现,但构造了两个临时的String对象hello和world,1个临时的StringBuilder对象,1个最终的helloworld对象,而用StringBuilder的只用了一个StringBuilder对象和1个helloworld对象。
但我认为,就上面的例子,hello和world都是编译时常量,只会分配一次内存,不存在新建临时String对象一说,所以用+号和用StringBuilder性能是一样的,+号还少写点代码。单就两个字符串拼接来说, 不管是用+号,还是用StringBuilder的构造和append方法,都是预先要有两个String对象的,所以性能肯定是一样的。而如果jvm没对+号做优化,在大于两个字符串拼接时,如"hello"+"world"+"ni"+"hao",会多生成"helloworld","helloworldni"这两个临时对象,用StringBuilder就有必要了。而平常就两个字符串拼接而言,用+号即可,我的理解对么?请指教
...全文
407 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
crowgns 2010-02-02
  • 打赏
  • 举报
回复
0
2953
第一个差值不管怎么做都是0,这个优化....
我举的例子不合适,应该
String st1 = "hello" ;
st1 += "world";这样就合时了




[Quote=引用 13 楼 knightzhuwei 的回复:]
好吧 那么再来个例子
Java codeimport java.util.Date;publicclass Test {publicstaticvoid main(String args[]) {long t1=new Date().getTime();for(int i=0;i<10000000;i++){
String st1="hello"+"world";
}long t2=new Date().getTime();for(int j=0;j<10000000;j++){
StringBuilder sb=new StringBuilder("hello");
sb.append("world");
String st2= sb.toString();
}long t3=new Date().getTime();
System.out.println(t2-t1);
System.out.println(t3-t2);
}
}
这个可能会输出什么??
[/Quote]
xietingyan 2010-02-01
  • 打赏
  • 举报
回复
String str1 = "hello" + "world"; 难道没有编译器优化吗?
knightzhuwei 2010-02-01
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 crowgns 的回复:]
    块1为什么性能会远高于块2呢?我本以为是块1和块2性能一样。javap -c生成的字节码以前没看过,你能大概解释一下块1性能远高于块2的原因么

[/Quote]
上面搞错了 应该引的是这个
public class Test {
public static void main(String args[]) {
String str1 = "hello" + "world";
String str2="helloworld";
System.out.println(str1==str2);
}
}


结果是什么
knightzhuwei 2010-02-01
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 keeya0416 的回复:]
次数少的时候确实没什么区别
数量大的话 StringBuilder 的优点就出来了
[/Quote]

public class Test {
public static void main(String args[]) {
String str1 = "hello" + "world";
String str2="helloworld";
System.out.println(str1==str2);
}
}

结果是什么?
amdgaming 2010-02-01
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 crowgns 的回复:]
块1为什么性能会远高于块2呢?我本以为是块1和块2性能一样。javap -c生成的字节码以前没看过,你能大概解释一下块1性能远高于块2的原因么

引用 1 楼 darxin 的回复:
{ // 块1
  String str = "hello" + "world";
}

{ // 块2
  StringBuffer buffer = new StringBuffer("hello");
  buffer.append("world");
  String str = buffer.toString();
}

{ // 块3
  String str = new String("hello");
  str += "world";
}

在JDK5.0环境下,块1的性能远高于块2,块2的性能稍高于块3。
因为JDK5.0对String的+操作进行了优化。

可用javap -c测试上述各块



[/Quote]

这种问题 真的 没什么 必要再讨论了,地球人都知道了。。。


crowgns 2010-02-01
  • 打赏
  • 举报
回复
块1为什么性能会远高于块2呢?我本以为是块1和块2性能一样。javap -c生成的字节码以前没看过,你能大概解释一下块1性能远高于块2的原因么

[Quote=引用 1 楼 darxin 的回复:]
{ // 块1
  String str = "hello" + "world";
}

{ // 块2
  StringBuffer buffer = new StringBuffer("hello");
  buffer.append("world");
  String str = buffer.toString();
}

{ // 块3
  String str = new String("hello");
  str += "world";
}

在JDK5.0环境下,块1的性能远高于块2,块2的性能稍高于块3。
因为JDK5.0对String的+操作进行了优化。

可用javap -c测试上述各块



[/Quote]
keeya0416 2010-02-01
  • 打赏
  • 举报
回复
次数少的时候确实没什么区别
数量大的话 StringBuilder 的优点就出来了
gao11811 2010-02-01
  • 打赏
  • 举报
回复
lz你这么分析是不全面的
就从你提供的代码来说,的确是一样的效果
但是,业务没有这么简单,这里String st1 = "hello" + "world";是同时在编译期就被整合了,但是通常的业务都会有循环增加和替换
比如:
String temp="hello"+"world";
for(int x=0;x<100;x++){
temp=temp+x;
}
这种情况下,效率和空间占用就完全不一样了。

当然,我们也应该就事论事,就lz这种情况来说,编译器的确是等同处理的

smartcatiboy 2010-02-01
  • 打赏
  • 举报
回复
由于对string优化的原因,现在的+会内建sbuffer
so:string+string和stringbuffer.append一样的效果

老版本jre例外

myj870517 2010-02-01
  • 打赏
  • 举报
回复
兄弟你这是SCJP常考的题目,我考了原来发现这种题目完全没用,现在看了你的还觉得貌似有点用,还能剩内存!哈哈,但是话说回来了,我还是觉得代码怎么好理解怎么写好,+号多么直观,不就内存吗?要就在插个几条,哈哈
liwis521125 2010-02-01
  • 打赏
  • 举报
回复
只是编译时用StringBuilder用快一点,而运行的速度是一样的~~~你 可以看编译后的代码,实际上两者是一样的,只补过JVM帮我们把“+”自动改成了创建StringBuilder了那种而已~~
TillPerfect 2010-02-01
  • 打赏
  • 举报
回复
当面对多次的字符串连接操作时,自然还是不使用“+”为好。
darxin 2010-02-01
  • 打赏
  • 举报
回复
{ // 块1
String str = "hello" + "world";
}

{ // 块2
StringBuffer buffer = new StringBuffer("hello");
buffer.append("world");
String str = buffer.toString();
}

{ // 块3
String str = new String("hello");
str += "world";
}

在JDK5.0环境下,块1的性能远高于块2,块2的性能稍高于块3。
因为JDK5.0对String的+操作进行了优化。

可用javap -c测试上述各块



welllit 2010-02-01
  • 打赏
  • 举报
回复
晕了,
临碣 2010-02-01
  • 打赏
  • 举报
回复
不是都说两次以上的是SB么?没人说过一次也必须SB吧?

楼主鸡动啥
knightzhuwei 2010-02-01
  • 打赏
  • 举报
回复
好吧 那么再来个例子
import java.util.Date;

public class Test {
public static void main(String args[]) {
long t1=new Date().getTime();
for(int i=0;i<10000000;i++){
String st1 = "hello" + "world";
}
long t2=new Date().getTime();
for(int j=0;j<10000000;j++){
StringBuilder sb = new StringBuilder("hello");
sb.append("world");
String st2 = sb.toString();
}
long t3=new Date().getTime();
System.out.println(t2-t1);
System.out.println(t3-t2);
}
}

这个可能会输出什么??

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧