首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

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

2012-01-28 
StringBuilder被过于神话,包括java,.net2个阵营我都看见有人神话他Java codelong startTime System.curr

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);                   }} 


[解决办法]
我不知你是怎么测试的,3种代码,我分开测试,每种跑6次,我贴一下我机器上的时间:
第一种,用StringBuilder:(将StringBuilder对象在循环外声明,然后delete)
1882、1860、1952、1949、1953、1946
用Stringbuilder:(将StringBuilder对象在循环内声明)
3814、3795、4137、3940、4117、3965
第二种,用+:
3932、4034、4051、4023、4008、4035
第三种,你那个写法用的时间和前两种不是一个数量级上的,要慢很多,但是你这种测试代码和之前的没比较性,我觉得应该这么写:

Java code
        for (int i = 0; i < 10000; i++) {                        for (int j = 0; j < 1000; j++) {                String add = "a"; //把这个add放在这个循环内,才能表现出创建100000000次                add += aaa;            }        }
[解决办法]
NND,应该占个沙发在回帖的,噼里啪啦的跑一通,打一堆,最后连沙发都没了
[解决办法]
上面是5,6,7的结果。
这个是1.4的结果:
Java code
javap -c ExampleCompiled from "Example.java"public class Example {  public Example();    Code:       0: aload_0              1: invokespecial #1                  // Method java/lang/Object."<init>":()V       4: return          public static void main(java.lang.String[]);    Code:       0: ldc           #2                  // String aaa       2: astore_1             3: ldc           #3                  // String ccc       5: astore_2             6: ldc           #4                  // String ddd       8: astore_3             9: ldc           #4                  // String ddd      11: astore        4      13: ldc           #4                  // String ddd      15: astore        5      17: ldc           #4                  // String ddd      19: astore        6      21: ldc           #4                  // String ddd      23: astore        7      25: invokestatic  #5                  // Method java/lang/System.currentTimeMillis:()J      28: lstore        8      30: iconst_0            31: istore        10      33: iload         10      35: ldc           #6                  // int 10000000      37: if_icmpge     100      40: new           #7                  // class java/lang/StringBuffer      43: dup                 44: invokespecial #8                  // Method java/lang/StringBuffer."<init>":()V      47: aload_1             48: invokevirtual #9                  // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;      51: ldc           #10                 // String accc      53: invokevirtual #9                  // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;      56: aload_2             57: invokevirtual #9                  // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;      60: ldc           #11                 // String vvvc      62: invokevirtual #9                  // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;      65: aload_3             66: invokevirtual #9                  // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;      69: aload         4      71: invokevirtual #9                  // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;      74: aload         5      76: invokevirtual #9                  // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;      79: aload         6      81: invokevirtual #9                  // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;      84: aload         7      86: invokevirtual #9                  // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;      89: invokevirtual #12                 // Method java/lang/StringBuffer.toString:()Ljava/lang/String;      92: astore        11      94: iinc          10, 1      97: goto          33     100: getstatic     #13                 // Field java/lang/System.out:Ljava/io/PrintStream;     103: invokestatic  #5                  // Method java/lang/System.currentTimeMillis:()J     106: lload         8     108: lsub               109: invokevirtual #14                 // Method java/io/PrintStream.println:(J)V     112: return        } 


[解决办法]
挺好的帖子。。。就这么被我给水了。。。

热点排行