从字符串拼接上来讲用String的concat比StringBuilder和StringBuffer的append性能都要好 为什么大家讨论最多的是append而不是concat呢public class ConcatVSAppend {
public static void main(String[] args) {
long[] timeStringconcat=new long[10];
long[] timeStringBuffer=new long[10];;
long[] timeStringBuilder=new long[10];;
for(int x=0;x<10;x++)
{
System.out.println("-----------第"+(x+1)+"次------------------");
long startTime1=System.currentTimeMillis();
String str1="字符串拼接 ";
for(int i=0;i<100000;i++)
{
str1.concat("第aaa一次连接");
str1.concat("第bbb二次连接");
str1.concat("第ccc三次连接");
}
long endTime1=System.currentTimeMillis();
timeStringconcat[x]=(endTime1-startTime1);
System.out.println("使用String.concat()经过10W次拼接耗时:"+timeStringconcat[x]+"毫秒");

long startTime2=System.currentTimeMillis();
StringBuffer sbr1=new StringBuffer("字符串拼接");
sbr1.ensureCapacity(100000);
for(int i=0;i<100000;i++)
{
sbr1.append("第aaa一次连接");
sbr1.append("第bbb二次连接");
sbr1.append("第ccc三次连接");
}
long endTime2=System.currentTimeMillis();
timeStringBuffer[x]=(endTime2-startTime2);
System.out.println("使用StringBuffer.append()经过10W次拼接耗时:"+timeStringBuffer[x]+"毫秒");

long startTime3=System.currentTimeMillis();
StringBuilder sbd1=new StringBuilder("字符串拼接");
sbd1.ensureCapacity(100000);
for(int i=0;i<100000;i++)
{
sbd1.append("第aaa一次连接");
sbd1.append("第bbb二次连接");
sbd1.append("第ccc三次连接");
}
long endTime3=System.currentTimeMillis();
timeStringBuilder[x]=(endTime3-startTime3);
System.out.println("使用StringBuilder.append()经过10W次拼接耗时:"+timeStringBuilder[x]+"毫秒");
System.out.println("----------------------------------");
}
System.out.println("平均值:");
long result=0l;
for(long avg:timeStringconcat)
{
result+=avg;
}
System.out.println(result/10.0);
result=0l;
for(long avg:timeStringBuffer)
{
result+=avg;
}
System.out.println(result/10.0);
result=0l;
for(long avg:timeStringBuilder)
{
result+=avg;
}
System.out.println(result/10.0);
}
}>>>>>>>>测试结果:-----------第1次------------------
使用String.concat()经过10W次拼接耗时:46毫秒
使用StringBuffer.append()经过10W次拼接耗时:63毫秒
使用StringBuilder.append()经过10W次拼接耗时:47毫秒
----------------------------------
-----------第2次------------------
使用String.concat()经过10W次拼接耗时:47毫秒
使用StringBuffer.append()经过10W次拼接耗时:31毫秒
使用StringBuilder.append()经过10W次拼接耗时:47毫秒
----------------------------------
-----------第3次------------------
使用String.concat()经过10W次拼接耗时:31毫秒
使用StringBuffer.append()经过10W次拼接耗时:31毫秒
使用StringBuilder.append()经过10W次拼接耗时:47毫秒
----------------------------------
-----------第4次------------------
使用String.concat()经过10W次拼接耗时:31毫秒
使用StringBuffer.append()经过10W次拼接耗时:47毫秒
使用StringBuilder.append()经过10W次拼接耗时:47毫秒
----------------------------------
-----------第5次------------------
使用String.concat()经过10W次拼接耗时:31毫秒
使用StringBuffer.append()经过10W次拼接耗时:32毫秒
使用StringBuilder.append()经过10W次拼接耗时:47毫秒
----------------------------------
-----------第6次------------------
使用String.concat()经过10W次拼接耗时:31毫秒
使用StringBuffer.append()经过10W次拼接耗时:47毫秒
使用StringBuilder.append()经过10W次拼接耗时:47毫秒
----------------------------------
-----------第7次------------------
使用String.concat()经过10W次拼接耗时:31毫秒
使用StringBuffer.append()经过10W次拼接耗时:47毫秒
使用StringBuilder.append()经过10W次拼接耗时:31毫秒
----------------------------------
-----------第8次------------------
使用String.concat()经过10W次拼接耗时:47毫秒
使用StringBuffer.append()经过10W次拼接耗时:47毫秒
使用StringBuilder.append()经过10W次拼接耗时:31毫秒
----------------------------------
-----------第9次------------------
使用String.concat()经过10W次拼接耗时:31毫秒
使用StringBuffer.append()经过10W次拼接耗时:47毫秒
使用StringBuilder.append()经过10W次拼接耗时:31毫秒
----------------------------------
-----------第10次------------------
使用String.concat()经过10W次拼接耗时:32毫秒
使用StringBuffer.append()经过10W次拼接耗时:46毫秒
使用StringBuilder.append()经过10W次拼接耗时:32毫秒
----------------------------------
平均值:
35.8
43.8
40.7

解决方案 »

  1.   

    String.concat()会把两个String   连起来然后产生一个新的String,本身没有变。StringBuffer 不同,它会把append中的东西放在自己后面,本身变了。
    但是看到lz测试,好像concat效率也不错。
    顶下
      

  2.   

    String的
     public String concat(String str) {
    int otherLen = str.length();
    if (otherLen == 0) {
        return this;
    }
    char buf[] = new char[count + otherLen];
    getChars(0, count, buf, 0);
    str.getChars(0, otherLen, buf, count);
    return new String(0, count + otherLen, buf);
        }
    StringBuffer和StringBuilderpublic AbstractStringBuilder append(String str) {
    if (str == null) str = "null";
            int len = str.length();
    if (len == 0) return this;
    int newCount = count + len;
    if (newCount > value.length)
        expandCapacity(newCount);
    str.getChars(0, len, value, count);
    count = newCount;
    return this;
        }
      

  3.   


    StringBuffer和StringBuilderJava code
    public AbstractStringBu…你想说什么…
    [/Quote]
    呵呵。
      

  4.   

    楼主似乎没理解StringBuffer的真谛StringBuffer sb = new StringBuffer(length);
    可以初始化length,如果length足够大,append就无需分配新的内存,只是简单复制,速度就提升了反之,如楼主的测试代码,StringBuffer重新分配内存频率太高了,
    而append方法中必须判断空间是否足够,自然比String慢了,String无需判断,直接分配新空间
      

  5.   

    题目没看全,有些偏差,纠正一下
    是sbr1.ensureCapacity(100000);写错了
    至少是100000*("第aaa一次连接").length()
      

  6.   

    我还真没考虑到ensureCapacity()
    是100000*("第aaa一次连接").length()好像也不够大吧 再加一个零就能比出来了
    可到底这个length该多大呢
      

  7.   

    StringBuffer做修改内容 操作 速度不是盖的 
      

  8.   

      进来 学习 学习  StringBuffer 速率 这么快?
      

  9.   

    fosjos 说的对,不过还有,你append的字符串好像都是常量字符串,如果你这里改成append变量,效果应该会更加明显的
      

  10.   

      str1.concat("第aaa一次连接");
      str1.concat("第bbb二次连接");
      str1.concat("第ccc三次连接");如果这里的concat 变成了 
      str1.concat("第" + i + "一次连接");
      str1.concat("第" + i + "二次连接");  
      str1.concat("第" + i + "三次连接");优势将会更加明显当然你也可以写成
      str1.concat("第");
      str1.concat(i);
     str1.concat("一次连接");concat实际上就是一次full copy, 而stringBuffer和stringBuilder实现上是append进去了,所以效率会更高
    如果好像你这样常量值的append, stringbuffer和stringbuilder是没有优势可言的,相反地,他需要有更多的判断,所以效率会更低
      

  11.   


    我测了下
    还是String的concat比较快啊
      

  12.   


    第二段:stringbuffer和stringbuilder需要做什么判断?你最开始说是预先设定length的值我明白是那样 对于数据类型来说 常量比变量会让stringbuffer和stringbuilder 消耗更多时间和内存吗?
      

  13.   

    其实可以直接看append和concat方法的源码很清楚两者的区别里面开销最大的应该是System.arraycopy其次是new所以两者在这些方面比较一下就没有问题了
      

  14.   

    没见append、concat源码里有关于System.arraycopy的内容啊 再说这里讨论的不是数组copy
      

  15.   

    看来楼主看源码的能力有待提高
    String.getChars就是arraycopy实现的比较时间复杂度,当然是比较开销最大的几个操作的执行次数
    我也不多解释了,直接看源码吧,追溯到native方法为止(例如System.arrraycopy)
      

  16.   

    我还真不懂怎么看 如三楼给出的
    String的 Java code public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        char buf[] = new char[count + otherLen];
        getChars(0, count, buf, 0);
        str.getChars(0, otherLen, buf, count);
        return new String(0, count + otherLen, buf);
        }
    StringBuffer和StringBuilder public AbstractStringBuilder append(String str) {
        if (str == null) str = "null";
            int len = str.length();
        if (len == 0) return this;
        int newCount = count + len;
        if (newCount > value.length)
            expandCapacity(newCount);
        str.getChars(0, len, value, count);
        count = newCount;
        return this;
        }
    都有getChars方法这个方法最终都需要经过System.arrraycopy方法的处理
    这就是StringBufferStringBuilder、String的区别是在new上?
      

  17.   

    string每次改变都要分配内存空间,而stringbuffer不要哦
      

  18.   

    string每次改变都要分配内存空间,而stringbuffer不要哦光看性能,不看内存。我们用StringBuffer的原因是什么呢?请考虑清楚。
      

  19.   

    老大发话了,呵呵
    不过,性能也应该是stringbuffer高
    空间分配少,copy次数也少,new次数也少
    stringbuffer只是增加了判断空间的开销
      

  20.   

    StringBuffer是可以修改的,同时要求线程安全,这有可能带来性能的损失。在不涉及到多线程的情况下StringBuilder更好。
    考虑到性能,String的+字符串连接操作符java都是使用StringBuilder的append方法来实现的,而不是使用String的concat方法,肯定实现的时候考虑的是StringBuilder的append方法要比String的concat性能好。
      

  21.   


    看来fosjos 对源码很有研究哟!当看到了native方法 就要去看jvm源码啦不知道你研究过这不?
      

  22.   

    楼主的方法, 估计JVM会骂, “谁TMD这么不负责, 把一堆String对象创建了还不使用, XXX"
      

  23.   

    StringBuffer是mutable类,为了保证线程安全,进行改写的方法都是synchronized来保护,当然慢点
    String是immutable类,里面的方法都不用synchronized就可以保证线程安全,因为永远不会修改String的属性二者的选择:当属性需要频繁修改时,用StringBuffer(若用String空间将占用很多),属性不需要修改时,用String
    速度的话当然都是String快