StringBuilder.append 中出现加号影响效率

标题中所说的情况为StringBuilder.append(str + "abc")类似这种情况  在append中再次使用“+”进行拼接

StringBuilder在字符串拼接中是最快的,有些时候使用不当会影响效率,先看一个例子

public class Test {

	public static void main(String[] args) {
		String str = "a";
		System.out.println(str + "b");//1
		
		//System.out.println("a" + "b");//2
	
	}

}

代码中1,2两部分输出结果都是一样的,但实际上第二个速度会快些,换句话说就是第二种比第一种高效。。。

这里也不能说是高效吧,应该是第一种写法有点多余了,,多干了一些活

使用javap命令可以很容易看清两者的区别 (使用方法 javap -c  xxx.class)(如果提示找不到该命令,装一下jdk配一下环境变量即可)

注释掉2只显示1的效果 即打印System.out.println(str + "b");

javac Test.java

javap -c Test.class
Compiled from "Test.java"
public class Test {
  public Test();
    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 a
       2: astore_1
       3: getstatic     #3                  // Field java/lang/System.out:Ljava/
io/PrintStream;
       6: new           #4                  // class java/lang/StringBuilder
       9: dup
      10: invokespecial #5                  // Method java/lang/StringBuilder."<
init>":()V
      13: aload_1
      14: invokevirtual #6                  // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      17: ldc           #7                  // String b
      19: invokevirtual #6                  // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      22: invokevirtual #8                  // Method java/lang/StringBuilder.to
String:()Ljava/lang/String;
      25: invokevirtual #9                  // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
      28: return
}

注释掉1只显示2的效果 即打印System.out.println("a" + "b");

javac Test.java
javap -c Test.class
Compiled from "Test.java"
public class Test {
  public Test();
    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 a
       2: astore_1
       3: getstatic     #3                  // Field java/lang/System.out:Ljava/
io/PrintStream;
       6: ldc           #4                  // String ab
       8: invokevirtual #5                  // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
      11: return
}

第一步都是先使用javac编译成class文件;

很容易看到第一种里面有一个StringBuilder,

具体步骤就是先创建一个字符串对象a;

然后创建对象StringBuilder,把字符串a添加到StringBuilder中;

然后创建字符串对象b,再把b添加到StringBuilder中;

最后调用StringBuilder中的toString得到字符串


但是第二种是直接创建字符串对象 ab,然后直接打印,省去了一部分操作,


因为第一种是变量+字符串,这里就会采用StringBuilder这种方式 (这原本是一种优化方式。。。)


同理来看看这段代码

public class Test {

	public static void main(String[] args) {
		String str = "a";

		StringBuilder builder = new StringBuilder();
		//builder.append(str + "b");//1
		builder.append("a" + "b");//2
		
	}

}



同样的道理 先看第一种builder.append(str + "b");

avac Test.java

javap -c Test.class
Compiled from "Test.java"
public class Test {
  public Test();
    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 a
       2: astore_1
       3: new           #3                  // class java/lang/StringBuilder
       6: dup
       7: invokespecial #4                  // Method java/lang/StringBuilder."<
init>":()V
      10: astore_2
      11: aload_2
      12: new           #3                  // class java/lang/StringBuilder
      15: dup
      16: invokespecial #4                  // Method java/lang/StringBuilder."<
init>":()V
      19: aload_1
      20: invokevirtual #5                  // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      23: ldc           #6                  // String b
      25: invokevirtual #5                  // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      28: invokevirtual #7                  // Method java/lang/StringBuilder.to
String:()Ljava/lang/String;
      31: invokevirtual #5                  // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      34: pop
      35: return
}

再看第二种builder.append("a" + "b");

javac Test.java

javap -c Test.class
Compiled from "Test.java"
public class Test {
  public Test();
    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 a
       2: astore_1
       3: new           #3                  // class java/lang/StringBuilder
       6: dup
       7: invokespecial #4                  // Method java/lang/StringBuilder."<
init>":()V
      10: astore_2
      11: aload_2
      12: ldc           #5                  // String ab
      14: invokevirtual #6                  // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      17: pop
      18: return
}

最大的区别就是第一个里面的StringBuilder好多,,,一大堆,仔细看会发现第一种里面有两个地方new StringBuilder 

第一个地方是源代码中就有new 第二个地方是在str + “b”的时候,原理的最开始一样


所以在StringBuilder的append里面就不要出现 变量 + 变量 或 + 字符串的情况为好!


=========================================================================================

javap参数展示

javap
Usage: javap <options> <classes>
where possible options include:
  -help  --help  -?        Print this usage message
  -version                 Version information
  -v  -verbose             Print additional information
  -l                       Print line number and local variable tables
  -public                  Show only public classes and members
  -protected               Show protected/public classes and members
  -package                 Show package/protected/public classes
                           and members (default)
  -p  -private             Show all classes and members
  -c                       Disassemble the code
  -s                       Print internal type signatures
  -sysinfo                 Show system info (path, size, date, MD5 hash)
                           of class being processed
  -constants               Show static final constants
  -classpath <path>        Specify where to find user class files
  -bootclasspath <path>    Override location of bootstrap class files


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值