日期:2014-05-20  浏览次数:20932 次

StringBuilder被过于神话,包括java,.net2个阵营我都看见有人神话他
Java code

        long startTime = System.currentTimeMillis();
        String aaa = "aaa";
        String ccc = "ccc";
        String ddd = "ddd";
        String eee = "ddd";
        String fff = "ddd";
        String ggg = "ddd";
        String hhh = "ddd";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 10000000; i++) {
            sb.append(aaa);
            sb.append("accc");
            sb.append(ccc);
            sb.append("vvvc");
            sb.append(ddd);
            sb.append(eee);
            sb.append(fff);
            sb.append(ggg);
            sb.append(hhh);
            sb.delete(0, sb.length());
        }
//1.................
        System.out.println(System.currentTimeMillis() - startTime);
        
        try {
            Thread.sleep(1000);
        }
        catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            String acc = aaa+"accc"+ccc+"vvvc"+ddd+eee+fff+ggg+hhh;
        }
//2.................
        System.out.println(System.currentTimeMillis() - startTime);
        
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            String add = "a";
            for (int j = 0; j < 1000; j++) {
                add += aaa;
            }
        }
//3.................
        System.out.println(System.currentTimeMillis() - startTime);



测试之后结果很明显:
1 和 2时间差不多. 1显得稍微高效一点. 
  -- 但是你别忘记了,很多时候你都是new的StringBuilder对象而不是 写StringBuilder.delete 进行重复使用.
如果把new StringBuilder 的代码换到循环体里面,你会发现 StringBuilder 的效率还不如 String = +..+..+

3的时间花费令人叹服. -- 太慢了.
这也是传统意义上不停有人叫嚷 别用 String 拼接字符串 要使用 StringBuilder 的最根本性原因.
但是你有没有发现他的独特性? ---> '+='

总结一下吧:
1,如果你的需求仅仅是: String = int变量+"ccc"+String变量+String变量+String变量 的话; 那么,不要使用StringBuilder 
  -- 你是不是经常看见 有人在拼接一个明显不需要for循环的 url 的时候 采取StringBuilder 方式,并且还是和new的StringBuilder临时变量?
  -- 你是不是经常看见 有人在拼接一个明显不需要for循环的 log 输出字符串的时候 采取StringBuilder 方式?


2,如果你要用一个for循环来拼接一个 String 的话. 那么,不要使用String ;

3,出于线程并发考虑,我同时也不推荐使用StringBuilder作为全局变量.

------解决方案--------------------
1 基本没看见过你说的这情况,我都是String直接拼

------解决方案--------------------
特地跑去找了些东西
Optimization of String Concatenation 

An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class (§20.13) or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression. 

String的+本来就是用StringBuilder(JDK 5或以上)或StringBuffer(JDK 1.4或以下)实现的。 
关键问题是:是不是同一个StringBuilder/StringBuffer。

在循环里用+=之类的方式来拼接字符串的问题就出在每轮循环里都new了一个StringBuilder/StringBuffer来做拼接,然后toString()完就抛弃了,等下轮循环进来又再new一个。 

以上全部从RednaxelaFX博客里面翻出来的东西
http://rednaxelafx.iteye.com/blog/1042464
神不神话什么的完全看你怎么用.
------解决方案--------------------
Java code
public class Example {
    public static void main(String[] args) {
        String aaa = "aaa";
        String ccc = "ccc";
        String ddd = "ddd";
        String eee = "ddd";
        String fff = "ddd";
        String ggg = "ddd";
        String hhh = "ddd";
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            String acc = aaa+"accc"+ccc+"vvvc"+ddd+eee+fff+ggg+hhh;
        }
        System.out.println(System.currentTimeMillis() - startTime);               
    }
}