<
>

StringBuider 在什么条件下、如何使用效率更高

2020-06-30 13:00:56 来源:易采站长站 作者:于丽

测试结果

测试结果如下

结果分析

第一组

10_000_000 次循环拼接,在循环内使用 String 和 StringBuilder 的效率是一样的!为什么呢?

使用 javap -c StringTest.class 反编译查看两个方法编译后的文件:

可以发现 String 方法拼接字符串编译器优化后使用的就是 StringBuilder、因此用例1 和用例2 的效率是一样的。

第二组

第二组的结果就是大家喜闻乐见的了,由于 10_000_000 次循环String 拼接实在太慢所以我采用了 10_000 次拼接来分析。

分析用例3:虽然编译器会对 String 拼接做优化,但是它每次在循环内创建 StringBuilder 对象,在循环内销毁。下次循环他有创建。相比较用例4在循环外创建,多了 n 次 new 对象、销毁对象的操作、n - 1 次将 StringBuilder 转换成 String 的操作 。效率低也是理所应当了。

扩展

第一组的测试还有一种写法:

 /**
  * 循环内 使用 StringBuilder 拼接字符串,一次循环后销毁
  */
 public static void useStringBuilderOut(){
  StringBuilder sb = new StringBuilder();
  for (int i = 0; i < CYCLE_NUM_BIGGER; i++) {
//   sb.setLength(0);
   sb.delete(0, sb.length());
   String s = sb.append(str1).append(i).append(str2).append(i).append(str3).append(i).append(str4).toString();
  }
 }

循环外创建 StringBuilder 每次循环开始的时候清空 StringBuilder 的内容然后拼接。这种写法无论使用 sb.setLength(0); 还是 sb.delete(0, sb.length()); 效率都比直接在循环内使用 String / StringBuilder 慢。奈何才疏学浅我一直想不明白为什么他慢。我猜测是 new 对象的速度比重置长度慢,于是这样测试了以下:

 public static void createStringBuider() {
  for (int i = 0; i < CYCLE_NUM_BIGGER; i++) {
   StringBuilder sb = new StringBuilder();
  }
 }

 public static void cleanStringBuider() {
  StringBuilder sb = new StringBuilder();
  for (int i = 0; i < CYCLE_NUM_BIGGER; i++) {
   sb.delete(0, sb.length());
  }
 }

但是结果是 cleanStringBuider 更快。让我摸不着头脑

如果有大神看到希望可以帮忙分析分析

结论

编译器会将 String 拼接优化成使用 StringBuilder,但是还是有一些缺陷的。主要体现在循环内使用字符串拼接,编译器不会创建单个 StringBuilder 以复用

对于多次循环内拼接一个字符串的需求:StringBuilder 很快,因为其避免了 n 次 new 对象、销毁对象的操作,n - 1 次将 StringBuilder 转换成 String 的操作

StringBuilder 拼接不适用于循环内每次拼接即用的操作方式。因为编译器优化后的 String 拼接也是使用 StringBuilder 两者的效率一样。后者写起来还方便...

暂时禁止评论

微信扫一扫

易采站长站微信账号