博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
String的'+'的性能及原理
阅读量:7075 次
发布时间:2019-06-28

本文共 2888 字,大约阅读时间需要 9 分钟。

逛了几个论坛。

不少人在讨论String的“+”,StringBuilder与StringBuffer等一系列的问题。先不多说了了

现分类详述:

1、String的‘+’,底层运行。及效率问题

2、StringBilder与StringBuffer的比較

本篇博文先介绍第一个问题

为了让大家看明确,

我们举例说明吧!

为了加深理解,我们能够来做几个小实验。



javac Test         编译文件
javap -c Test   查看虚拟机指令

实验一:纯字符串

public class Test {    public static void main(String args[]) {        String str = "a";    }}
// 将字符串 a 存入常数池

   0:   ldc     #2; //String a

   
// 将引用存放到 1 号局部变量中

   2:   astore_1

   3:   return

实验二:纯字符串相加

public class Test {    public static void main(String args[]) {        String str = "a" + "b";    }}


   
// 将字符串 ab 压入常数池

   0:   ldc     #2; //String ab

   2:   astore_1

   3:   return


实验二能够非常明显地看出,编译器在编译时产生的字节码已经将 "a" + "b" 优化成了 "ab",

同理多个字符串的相加也会被优化处理,
须要注意的是字符串常量相加


实验三:字符串与自己主动提升常量相加

public class Test {    public static void main(String args[]) {        String str = "a" + (1 + 2);    }}
// 将字符串 a3 压入常数池

   0:   ldc     #2; //String a3

   2:   astore_1

   3:   return


通过虚拟机指令能够看出,1 + 2 自己主动提升后的常量与字符串常量,虚拟机也会对其进行优化。



实验二、实验三结论:常量间的相加并不会引起效率问题


实验四:字符串与变量相加

public class Test {    public static void main(String args[]) {        String s = "b";        String str = "a" + s;    }}
// 将字符串 b 压入常数池

   0:   ldc     #2; //String b

   
// 将引用存放到 1 号局部变量中

   2:   astore_1

   
// 检查到很量的相加。这时创建 StringBuilder 对象

   3:   new     #3; //class java/lang/StringBuilder

   
// 从栈中复制出数据。即把字符串 b 复制出来

   6:   dup

   
// 调用 StringBuilder 的初始构造

   7:   invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V

   
// 将字符串 a 压入常数池

   10:  ldc     #5; //String a

   
// 调用 StringBuilder 的 append 方法,把字符串 a 加入进去

   12:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

   
// 从 1 号局部变量中载入数据引用

   15:  aload_1

   
// 调用 StringBuilder 的 append 方法,把字符串 b 加入进去

   16:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

   
// 调用 StringBuilder 的 toString 方法

   19:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;

   
// 将 toString 的结果保存至 2 号局部变量

   22:  astore_2

   23:  return


实验四能够看出,很量字会串相加时,因为相加的变量中存放的是字符串的地址引用。

由于在编译时无法确切地知道其它详细的值,也就没有办法对其进行优化处理,这时为了

达到连接的效果,其内部採用了 StringBuilder 的机制进行处理(JDK 5 中新增的,我

这里没有 JDK 1.4,预计在 JDK 1.4 下採用的是 StringBuffer),将他们都 append

进去,最后用 toString 输出。



若 s 为其它类型时,比方:int 类型,也是採用同种方式进行处理。


同理。依据实验二的结果,在 String str = "a" + "b" + s; 时。先会优化成 "ab" 再与

s 依据实验四的方式进行处理。这时 StringBuilder 仅调用了两次 append 方法。


假设是 String str = "a" + s + "b"; 这样的形式的就没办法优化了。StringBuilder 得调

用三次 append 方法。


实验四的结论表明,字符串与变量相加时在内部产生了 StringBuilder 对象并採取了一定

的操作。


假设仅仅有一句 String str = "a" + s; 这样子的,其效率与

String str = new StringBuilder().append("a").append(s).toString();

是一样的。


一般所说的 String 採用连接运算符(+)效率低下主要产生在下面的情况中:

public class Test {    public static void main(String args[]) {        String s = null;        for(int i = 0; i < 100; i++) {            s += "a";        }    }}
每做一次 + 就产生个 StringBuilder 对象,然后 append 后就扔掉。下次循环再到达时重

新产生个 StringBuilder 对象。然后 append 字符串,如此循环直至结束。



假设我们直接採用 StringBuilder 对象进行 append 的话,我们能够节省 N - 1 次创建和

销毁对象的时间。

转载于:https://www.cnblogs.com/gavanwanggw/p/7134241.html

你可能感兴趣的文章
作为程序猿,我们生活在一个幸福的时代
查看>>
电脑网络连接问题汇总
查看>>
kali linux networking scanning Cookbok (第三章结尾笔记)
查看>>
NO12 useradd-passwd-uname-hostname命令-上传rz下载sz-批量部署- Linux用户相关操作
查看>>
CentOS 6.0 安装配置rails 2.3.11 + redmine 1.2.1 笔记
查看>>
正则表达式
查看>>
python loss layer: does not need backward computation?
查看>>
Shadow Mapping With PCF
查看>>
Cracking the Coding Interview-ch11 | System Design and Memory Limits
查看>>
ionic ng-repeat 循环传值
查看>>
63. 搜索旋转排序数组 II
查看>>
Java学生管理系统
查看>>
IOS UISearchDisplayController 点击搜索出现黑条问题解决方案
查看>>
如何在应用图标上显示未读消息
查看>>
P2P下载为什么人越多越快呢??
查看>>
iOS--警告收录及科学快速的消除方法
查看>>
Export-XLSX PowerShell generate real Excel XLSX files without Excel and COM
查看>>
Oracle 修改表列属性
查看>>
facl权限(getfacl/setfacl)
查看>>
Homework Exercises 1
查看>>