zoukankan      html  css  js  c++  java
  • StringBuilder的append、StringBuffer的append和String str = "a"+"b"的区别?

    大家都知道String+String会开销额外的系统资源,粗略的原因是String是不可变类,每一步操作都会返回新的String变量,占用空间及时间。
    其实我的理解不是这样的,我们来看看String+的底层实现。

    测试案例

    public static void main(String[] args) {
            String a = "a";
            StringBuilder b = new StringBuilder("b");
            StringBuffer c = new StringBuffer("c");
            long star = System.currentTimeMillis();
            for(int i=0;i<200000;i++){
                a+="a";
            }
            long end = System.currentTimeMillis();
            System.out.println("String:"+(end-star));
            
            star = System.currentTimeMillis();
            for(int i=0;i<200000;i++){
                b.append("b");
            }
            end = System.currentTimeMillis();
            System.out.println("StringBuilder:"+(end-star));
            
            star = System.currentTimeMillis();
            for(int i=0;i<200000;i++){
                c.append("c");
            }
            end = System.currentTimeMillis();
            System.out.println("StringBuffer:"+(end-star));
        }

    测试结果

    String:17735
    StringBuilder:6
    StringBuffer:7

    测试结论
    String+ 确实占用了太多的资源,处理效率非常低下。StringBuilder比StringBuffer更新了同步方法,性能有所提升。
    原因分析
    我用javap -verbose 查看已经编译好的class文件发现:

    public static void main(java.lang.String[]);
       flags: ACC_PUBLIC, ACC_STATIC
       Code:
         stack=6, locals=9, args_size=1
            0: ldc           #16                 // String a
            2: astore_1
            3: new           #18                 // class java/lang/StringBuilder
            6: dup
            7: ldc           #20                 // String b
            9: invokespecial #22                 // Method java/lang/StringBuilder.
    <init>":(Ljava/lang/String;)V
           12: astore_2
           13: new           #25                 // class java/lang/StringBuffer
           16: dup
           17: ldc           #27                 // String c
           19: invokespecial #29                 // Method java/lang/StringBuffer."
    init>":(Ljava/lang/String;)V
           22: astore_3
           23: invokestatic  #30                 // Method java/lang/System.current
    imeMillis:()J
           26: lstore        4
           28: iconst_0
           29: istore        6
           31: goto          57
           34: new           #18                 // class java/lang/StringBuilder
           37: dup
           38: aload_1
           39: invokestatic  #36                 // Method java/lang/String.valueOf
    (Ljava/lang/Object;)Ljava/lang/String;
           42: invokespecial #22                 // Method java/lang/StringBuilder.
    <init>":(Ljava/lang/String;)V
           45: ldc           #16                 // String a
           47: invokevirtual #42                 // Method java/lang/StringBuilder.
    ppend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
           50: invokevirtual #46                 // Method java/lang/StringBuilder.
    oString:()Ljava/lang/String;
           53: astore_1
           54: iinc          6, 1
           57: iload         6
           59: ldc           #50                 // int 100000
           61: if_icmplt     34
           64: invokestatic  #30                 // Method java/lang/System.current
    imeMillis:()J
           67: lstore        6
           69: getstatic     #51                 // Field java/lang/System.out:Ljav
    /io/PrintStream;
           72: new           #18                 // class java/lang/StringBuilder
           75: dup
           76: ldc           #55                 // String String:
           78: invokespecial #22                 // Method java/lang/StringBuilder.
    <init>":(Ljava/lang/String;)V
           81: lload         6
           83: lload         4
           85: lsub
           86: invokevirtual #57                 // Method java/lang/StringBuilder.
    ppend:(J)Ljava/lang/StringBuilder;
           89: invokevirtual #46                 // Method java/lang/StringBuilder.
    oString:()Ljava/lang/String;
           92: invokevirtual #60                 // Method java/io/PrintStream.prin
    ln:(Ljava/lang/String;)V
           95: invokestatic  #30                 // Method java/lang/System.current
    imeMillis:()J
           98: lstore        4
          100: iconst_0
          101: istore        8
          103: goto          116
          106: aload_2
          107: ldc           #20                 // String b
          109: invokevirtual #42                 // Method java/lang/StringBuilder.
    ppend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          112: pop
          113: iinc          8, 1
          116: iload         8
          118: ldc           #50                 // int 100000
          120: if_icmplt     106
          123: invokestatic  #30                 // Method java/lang/System.current
    imeMillis:()J
          126: lstore        6
          128: getstatic     #51                 // Field java/lang/System.out:Ljav
    /io/PrintStream;
          131: new           #18                 // class java/lang/StringBuilder
          134: dup
          135: ldc           #65                 // String StringBuilder:
          137: invokespecial #22                 // Method java/lang/StringBuilder.
    <init>":(Ljava/lang/String;)V
          140: lload         6
          142: lload         4
          144: lsub
          145: invokevirtual #57                 // Method java/lang/StringBuilder.
    ppend:(J)Ljava/lang/StringBuilder;
          148: invokevirtual #46                 // Method java/lang/StringBuilder.
    oString:()Ljava/lang/String;
          151: invokevirtual #60                 // Method java/io/PrintStream.prin
    ln:(Ljava/lang/String;)V
          154: invokestatic  #30                 // Method java/lang/System.current
    imeMillis:()J
          157: lstore        4
          159: iconst_0
          160: istore        8
          162: goto          175
          165: aload_3
          166: ldc           #27                 // String c
          168: invokevirtual #67                 // Method java/lang/StringBuffer.a
    pend:(Ljava/lang/String;)Ljava/lang/StringBuffer;
          171: pop
          172: iinc          8, 1
          175: iload         8
          177: ldc           #50                 // int 100000
          179: if_icmplt     165
          182: invokestatic  #30                 // Method java/lang/System.current
    imeMillis:()J
          185: lstore        6
          187: getstatic     #51                 // Field java/lang/System.out:Ljav
    /io/PrintStream;
          190: new           #18                 // class java/lang/StringBuilder
          193: dup
          194: ldc           #70                 // String StringBuffer:
          196: invokespecial #22                 // Method java/lang/StringBuilder.
    <init>":(Ljava/lang/String;)V
          199: lload         6
          201: lload         4
          203: lsub
          204: invokevirtual #57                 // Method java/lang/StringBuilder.
    ppend:(J)Ljava/lang/StringBuilder;
          207: invokevirtual #46                 // Method java/lang/StringBuilder.
    oString:()Ljava/lang/String;
          210: invokevirtual #60                 // Method java/io/PrintStream.prin
    ln:(Ljava/lang/String;)V
          213: return

    从编译的代码来看,String+的准确操作是:
    new StringBuilder()
    new String.valueof()
    StringBuilder.<init>
    StringBuilder.append()
    StringBuilder.toString()
    而StringBuilder的准确操作是:
    StringBuilder.append()
    而StringBuffer()的准确操作是:
    StringBuffer.append

    转自http://alqm1314-126-com.iteye.com/blog/1932879

  • 相关阅读:
    。。。
    __new__ 单例
    bokeh
    空间数据可视化
    关系网络图
    Pandas 50题练习
    seaborn
    数据输出及内容美化 简单介绍
    数据分析---项目总结
    数学建模
  • 原文地址:https://www.cnblogs.com/zyh1994/p/5845632.html
Copyright © 2011-2022 走看看