最近管理层要求把项目中所有的字符串“+”操作修改为StringBuilder/StringBuffer方式进行操作。以前在java5.0发布的时候好像看到过在这个新的编译器版本中对字符串的操作进行了优化,索性就彻底的研究下。
测试代码
String s1="********";
s1+="--------";
s1+="^^^^^^^^";
StringBuilder s2=new StringBuilder("********");
s2.append("--------");
s2.append("^^^^^^^^");
对应的class文件关键字节码
astore_1 [s1]//s1的是声明
3 new java.lang.StringBuilder [18]//JVM把s1优化为StringBuilder
6 dup
7 aload_1 [s1]
8 invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [20]
11 invokespecial java.lang.StringBuilder(java.lang.String) [26]
14 ldc <String "--------"> [29]
16 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [31]//执行“+”操作
19 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [35]//操作完成重新转化为String
22 astore_1 [s1]
23 new java.lang.StringBuilder [18]//再次把string转化为StringBuilder,重新执行上面的步骤
26 dup
27 aload_1 [s1]
28 invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [20]
31 invokespecial java.lang.StringBuilder(java.lang.String) [26]
34 ldc <String "^^^^^^^^"> [39]
36 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [31]
39 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [35]
42 astore_1 [s1]
43 new java.lang.StringBuilder [18]//最后转化为StringBuilder ,以备后面可能进行的字符串操作
46 dup
47 ldc <String "********"> [16]//下面是StringBuilder操作方式的字节码,可以看出没有进行String与StringBuilder的相互转化,直接append。
49 invokespecial java.lang.StringBuilder(java.lang.String) [26]
52 astore_2 [s2]
53 aload_2 [s2]
54 ldc <String "--------"> [29]
56 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [31]
59 pop
60 aload_2 [s2]
61 ldc <String "^^^^^^^^"> [39]
63 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [31]
这样基本可以得出结论:在5.0以后的版本,对于String直接进行"+"操作,java编译器会把其优化为StringBuilder后再进行append操作,然后进行来回的String<--->StringBuilder的转化,用StringBuilder的话可以会一直的append直道自己进行StringBuilder--->String的转化,因此在效率上String的“+”操作虽然简洁并比1.4以前的版本中的重新生成String对象进行操作有改进,但效率上仍然与StringBuilder有一定的差距,具体差距有多大,下面随便写了个测试代码
String str1="";
long start=System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
str1+="test";
}
str1+="--------";
long end=System.currentTimeMillis();
System.out.println("String耗时"+(end-start));
//StringBuilder
start=System.currentTimeMillis();
StringBuilder builder=new StringBuilder();
for (int i = 0; i < 50000; i++) {
builder.append("test");
}
builder.append("--------");
builder.toString();
end=System.currentTimeMillis();
System.out.println("StringBuilder耗时"+(end-start));
//随便测试下StringBuffer
start=System.currentTimeMillis();
StringBuffer buffer=new StringBuffer();
for (int i = 0; i < 50000; i++) {
buffer.append("test");
}
buffer.append("--------");
buffer.toString();
end=System.currentTimeMillis();
System.out.println("StringBuffer耗时"+(end-start));
结果:
String耗时7202
StringBuilder耗时16
StringBuffer耗时0
StringBuilder是线程非安全的,StringBuffer是线程安全的,按理来说StringBuilder应该比StringBuffer快才是,但结果有点出乎意料,可能是测试次数少的原因吧,过年了,先写这么多吧。
分享到:
相关推荐
4.2.2 字符串的length()方法与性能优化 4.2.3 tochararray()方法与性能优化 4.2.4 字符串转化为数字 4.3 系统i/o类 4.3.1 java语言中输入/输出流 4.3.2 通过系统缓冲流类提高i/o操作效率 4.3.3 通过自定制缓冲区提高...
Java 11主要包含了新的语法、改进的工具和增强的性能等方面的内容,如支持原始字符串字面量、增强了对lambda表达式中局部变量的类型推断、新增了G1垃圾收集器等。 Spring 5.0:Spring 5.0是Spring框架的最新版本,它...
能对输入的字符串进行验证,还能收藏你常用的正则规则。使用环境。jkd6.0 ,linux/windows操作系统 @echo ************************************* @echo ** *** @echo ** 请不要更改jar文件的名字 *** @echo ** ***...
8.14. replace:字符串替换实用工具 8.15. mysql_zap:杀死符合某一模式的进程 9. 语言结构 9.1. 文字值 9.1.1. 字符串 9.1.2. 数值 9.1.3. 十六进制值 9.1.4. 布尔值 9.1.5. 位字段值 9.1.6. NULL值 9.2. 数据库、...
·数值类型可以用2进制字符串表示,并且可以在字符串表示中添加下划线; 钻石型语法; nu值的自动处理。 Java 8 函数式接口 Lambda表达式 接口的增强 运行时数据区域包括哪些? 1.程序计数器 2.Java虚拟机栈 3.本地方法...
8.14. replace:字符串替换实用工具 8.15. mysql_zap:杀死符合某一模式的进程 9. 语言结构 9.1. 文字值 9.1.1. 字符串 9.1.2. 数值 9.1.3. 十六进制值 9.1.4. 布尔值 9.1.5. 位字段值 9.1.6. NULL值 9.2. 数据库、...
8.14. replace:字符串替换实用工具 8.15. mysql_zap:杀死符合某一模式的进程 9. 语言结构 9.1. 文字值 9.1.1. 字符串 9.1.2. 数值 9.1.3. 十六进制值 9.1.4. 布尔值 9.1.5. 位字段值 9.1.6. NULL值 9.2....
8.14. replace:字符串替换实用工具 8.15. mysql_zap:杀死符合某一模式的进程 9. 语言结构 9.1. 文字值 9.1.1. 字符串 9.1.2. 数值 9.1.3. 十六进制值 9.1.4. 布尔值 9.1.5. 位字段值 9.1.6. NULL值 9.2. ...
8.14. replace:字符串替换实用工具 8.15. mysql_zap:杀死符合某一模式的进程 9. 语言结构 9.1. 文字值 9.1.1. 字符串 9.1.2. 数值 9.1.3. 十六进制值 9.1.4. 布尔值 9.1.5. 位字段值 9.1.6. NULL值 9.2. 数据库、...
8.14. replace:字符串替换实用工具 8.15. mysql_zap:杀死符合某一模式的进程 9. 语言结构 9.1. 文字值 9.1.1. 字符串 9.1.2. 数值 9.1.3. 十六进制值 9.1.4. 布尔值 9.1.5. 位字段值 9.1.6. NULL值 9.2. 数据库、...
8.14. replace:字符串替换实用工具 8.15. mysql_zap:杀死符合某一模式的进程 9. 语言结构 9.1. 文字值 9.1.1. 字符串 9.1.2. 数值 9.1.3. 十六进制值 9.1.4. 布尔值 9.1.5. 位字段值 9.1.6. NULL值 9.2. 数据库、...
replace:字符串替换实用工具 8.15. mysql_zap:杀死符合某一模式的进程 9. 语言结构 9.1. 文字值 9.1.1. 字符串 9.1.2. 数值 9.1.3. 十六进制值 9.1.4. 布尔值 9.1.5. 位字段值 9.1.6....
Yauaa:另一个用户代理分析器 这是Java库的.NET移植,它试图解析和分析useragent字符串并提取尽可能多的相关属性。 您可以在以下链接中看到原始项目: : 该库已从头开始完全用C#重写,以进行优化和.NET友好可以在...
8.14. replace:字符串替换实用工具 8.15. mysql_zap:杀死符合某一模式的进程 9. 语言结构 9.1. 文字值 9.1.1. 字符串 9.1.2. 数值 http://doc.mysql.cn/mysql5/refman-5.1-zh.html-chapter/(第 8/24 页)2006-11...
15.5 字符串、日期、时间、BLOB和NULL 15.6 向关联数据表插入新数据记录 15.7 处理来自HTML表单的输入数据 15.8 分页显示查询结果 15.9 处理层次化数据 15.10 速度优化 15.11 Unicode 15.12 二进制...
o 7.1 文字:怎样写字符串和数字 + 7.1.1 字符串 + 7.1.2 数字 + 7.1.3 十六进制值 + 7.1.4 NULL值 + 7.1.5 数据库,表,索引,列和别名的命名 # 7.1.5.1 名字的大小写敏感性 o 7.2 用户变量 o 7.3 列类型 ...
15.5 字符串、日期、时间、BLOB和NULL 15.6 向关联数据表插入新数据记录 15.7 处理来自HTML表单的输入数据 15.8 分页显示查询结果 15.9 处理层次化数据 15.10 速度优化 15.11 Unicode 15.12 ...
6.14 怎样使MySQL安全以对抗解密高手(cracker) 7 MySQL 语言参考 7.1 文字:怎样写字符串和数字 7.1.1 字符串 7.1.2 数字 7.1.3 十六进制值 7.1.4 NULL值 7.1.5 数据库,表,索引,...