`
aine_pan
  • 浏览: 44844 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

String+=和StringBuilder.append以及StringBuffer.append的比较

阅读更多
大家都知道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<100000;i++){
			a+="a";
		}
		long end = System.currentTimeMillis();
		System.out.println("String:"+(end-star));
		
		star = System.currentTimeMillis();
		for(int i=0;i<100000;i++){
			b.append("b");
		}
		end = System.currentTimeMillis();
		System.out.println("StringBuilder:"+(end-star));
		
		star = System.currentTimeMillis();
		for(int i=0;i<100000;i++){
			c.append("c");
		}
		end = System.currentTimeMillis();
		System.out.println("StringBuffer:"+(end-star));
	}

测试结果
String:5355
StringBuilder:6
StringBuffer:9

测试结论
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
这样就可以理解为什么效率差这么多了!
分享到:
评论

相关推荐

    String ,StringBuffer与StringBuilder

    在 Java 中,String, StringBuffer 和 StringBuilder 三个类都是用于字符操作的,但它们之间有着很大的区别。 首先,String 是不可变类,意味着一旦创建了 String 对象,就不能修改它的值。每次对 String 对象的...

    Java StringBuffer & StringBuilder.pdf

    在Java编程语言中,`StringBuffer` 和 `StringBuilder` 是两个重要的类,它们主要用于处理可变的字符串。这两个类在很多方面都非常相似,但存在一些关键的区别。 **一、StringBuffer和StringBuilder的区别** 1. **...

    String、StringBuffer、StringBuilder的使用方法

    在Java编程语言中,`String`、`StringBuffer`和`StringBuilder`是处理字符串的三个重要类,它们各自有特定的使用场景和优缺点。理解它们的差异对于编写高效的代码至关重要。 **String类** `String`是不可变的类,...

    《剑指offer》Java-String、StringBuffer 和 StringBuilder 的区别.pdf

    在Java编程语言中,String、StringBuffer和StringBuilder都是用来处理字符串的对象,但它们之间存在显著的区别。String是最常见的字符串类型,它的特点是不可变性。这意味着一旦一个String对象被创建,就不能进行...

    Java中StringBuffer和StringBuilder_动力节点Java学院整理

    在Java编程语言中,`StringBuffer`和`StringBuilder`类都是用来处理字符串的,它们的主要功能是构建和操作字符串。这两个类与`String`类不同,`String`类是不可变的,这意味着一旦创建了一个`String`对象,就不能...

    StringBuffer和String_区别

    1. **单线程环境**:在这种情况下,推荐使用 **StringBuilder**,因为它不提供线程安全机制,所以在性能上优于 StringBuffer 和 String。 2. **多线程环境**: - 如果需要修改字符串内容,则应选择 **...

    从内存方面解释Java中String与StringBuilder的性能差异.docx

    这段代码在编译后会被转换成使用StringBuilder或StringBuffer的append方法,但由于String的不可变性,每次`+`操作都会生成新的String对象,这在大量拼接操作中会导致大量的内存分配和对象创建,效率较低。...

    Str---Copy.rar_There There

    此外,理解何时使用`StringBuilder`和`StringBuffer`(对于多线程环境)也是关键,它们能有效地避免不必要的字符串对象创建,从而提高性能。 压缩包中的"Str - Copy.java"文件可能包含了更多具体的示例和实现,你...

    String和StringBuilder、StringBuffer的区别1

    在Java编程语言中,`String`、`StringBuilder`和`StringBuffer`是处理字符串的三种主要类型,它们各自具有不同的特性和使用场景。下面将详细解释它们之间的主要区别。 首先,`String`类是最基本的字符串类型,它...

    String-StringBuffer-StringBuilder

    在Java编程语言中,`String`、`StringBuffer`和`StringBuilder`都是用来处理字符串的类,但它们之间存在显著的差异,主要体现在性能、线程安全性和使用场景上。 首先,`String`是最基本的字符串类,它代表的是不可...

    stringbuffer和string的区别.pdf

    在Java编程语言中,字符串处理是常见的需求,而对于字符串的操作,Java提供了两个常用类:String和StringBuffer。虽然两者都用于处理文本数据,但它们在实现和性能上有着本质的区别。 首先,String类是不可变的。这...

    JavaScript 利用StringBuffer类提升+=拼接字符串效率

    此外,虽然在现代JavaScript引擎中,V8(Chrome和Node.js的引擎)和SpiderMonkey(Firefox的引擎)都进行了优化,但对于大量的字符串操作,使用StringBuffer类依然可以提高性能。值得注意的是,自ECMAScript 6(ES6...

    String&StringBuffer&StringBuilder三者之间的区别-经典解析.doc

    在Java编程语言中,String、StringBuffer和StringBuilder都是用来处理字符串的重要类,它们各自有特定的使用场景和特性。理解这三个类的区别对于任何Java开发者,无论是初学者还是经验丰富的程序员,都是非常重要的...

    StringBuilders.jl:Julia的StringBuilder类型

    StringBuilders 概述 建立String的简单类型。 用法如下: using StringBuilders sb = StringBuilder () append! (sb, " First string " ) append! (sb, " Second string " ) s = String (sb) 与使用IOBuffer相比...

    OJ_simple_10.08.txt

    这段代码使用了`StringBuffer`来构建表格的上下边界以及中间的内容行。通过循环结构和字符串操作实现了简单的表格绘制功能。 ### 四、计算因数数量及输出因数列表 下面的代码用于计算一个整数的所有因数,并统计...

    JavaSE之StringBuilder类与String类

    ### JavaSE之StringBuilder类与String类 ...以上内容详细介绍了如何使用`String`和`StringBuilder`类,以及它们之间的区别。这对于JavaSE入门者来说是非常实用的知识点,希望这些知识点能够帮助到正在学习JavaSE的你。

    Java软件开发实战 Java基础与案例开发详解 9-2 StringBuffer和String Builder类共9页.pdf

    ### Java软件开发实战:StringBuffer和StringBuilder类 #### 1. 概述 在Java编程中,处理字符串是一项常见的需求。对于需要频繁修改的字符串,使用`String`类可能会导致性能问题,因为每次修改都会创建一个新的`...

    java基础--4.常用类-3.StringBuffer、StringBuilder

    在Java编程语言中,`StringBuffer`和`StringBuilder`是两个非常重要的类,它们主要用于处理字符串的拼接和修改操作。这两个类位于`java.lang`包下,因此在使用时无需显式导入。本篇文章将深入探讨这两个类的特性和...

    【Java基础笔记】String类以及StringBuffer Builder.docx

    本文主要关注Java中的三个字符串相关类:`String`、`StringBuilder`和`StringBuffer`。理解它们的特性和使用方法对于编写高效、线程安全的代码至关重要。 一、`String`类 `String`类在Java中是一个不可变类,意味着...

Global site tag (gtag.js) - Google Analytics