zoukankan      html  css  js  c++  java
  • 关于String和StringBuilder、StringBuffer的一个简单性能测试

    String a=String b + String c + String d

    这种代码在程序里应该随处可见,一部分人不知道这段代码的缺陷在哪,另一部分人知道这样写不好,但是太顺手了下意识就写了。

    在Java里,String是个不可变对象,所以右边的每次赋值操作都会new一个新对象,b+c,b+c+d,至少会new两个,很明显性能不佳。但是这个问题没有大多数情况下没我们想象的那么严重,因为编译器在编译时会对String做很多优化,但是对于一些运行时的赋值和修改操作,编译器很难优化,这种时候,就强烈不推荐这样写,虽然写的很顺手 ,但是性能不行,如果存在字符串的修改操作,就应该用StringBuilder和StringBuffer。

    下面,就用一个简单的测试,来看看他们之间的性能差别,让我们心里有数。

    1. 测试String直接拼接

     1     public static void main(String[] args) {
     2         long begin = System.currentTimeMillis();
     3         String str = "";
     4         for(int i=0;i<10000;i++){
     5             str = str+i;
     6         }
     7         long end = System.currentTimeMillis();
     8         long time = end - begin;
     9         System.out.println(time+"");
    10     }

    直接用String的拼接,循环调用10000次,跑出来结果是639毫秒

    2.测试String.concat拼接

     1     public static void main(String[] args) {
     2         long begin = System.currentTimeMillis();
     3         String str = "";
     4         for(int i=0;i<10000;i++){
     5             str = str.concat(String.valueOf(i));
     6         }
     7         long end = System.currentTimeMillis();
     8         long time = end - begin;
     9         System.out.println(time+"");
    10     }

    也是循环调用10000次,跑出来结果是322毫秒

    3.测试StringBuilder拼接

     1     public static void main(String[] args) {
     2         long begin = System.currentTimeMillis();
     3         StringBuilder sb = new StringBuilder();
     4         for(int i=0;i<10000;i++){
     5             sb.append(i);
     6         }
     7         long end = System.currentTimeMillis();
     8         long time = end - begin;
     9         System.out.println(time+"");
    10     }
    11 
    12 }

    同样循环调用10000次,结果是5毫秒。换成StringBuffer,结果也是一样。

    上面这个简单测试,可以用数据告诉我们,String和StringBuilder、StringBuffer之间的性能差距了,所以如果字符串有变更,都用StringBuilder和StringBuffer,而不是用简单粗暴的赋值操作,另外就是,上面可以看出,String的concat性能也明显优于直接拼接。

    关于StringBuilder和StringBuffer

    这两个操作可变字符串的类,都实现了AbstractStringBuilder抽象类,接口也几乎一样,他的最大区别是:StringBuffer基本所有方法都做了同步,而StringBuilder没有,换言之,StringBuffer是线程安全的,StringBuilder不是。所以这两个就根据不同的场景做取舍就ok。

    谢谢@assiwe提醒,由于编译器本身对String做了足够多的优化,对于简单的String操作,String不比StringBuilder差,因为本身开销都很少,这种时候苛求性能就没太多意义了,只有在我们对String操作的性能敏感的时候,才需要关注他们之间的性能差异,用的时候,要做到心里有数,明白为什么用这个而不用另一个。

  • 相关阅读:
    Could not load file or assembly Microsoft.SqlServer.management.sdk.sfc version 11.0.0.0
    代码覆盖率 (Code Coverage)从简到繁 (一)
    vscode配置自动格式化eslint 配置模板
    无效的源发行版: 10
    java读取一个文件写入另外一个文件
    notepad++使用正则表达式匹配
    jsp页面返回字符串而非方法执行后取得的数据?
    maven的原始setting.xml文件,自带阿里云镜像,之前配的时候出错,保存一下,注意可以在localRepository处设置存储依赖的地址,大概在49到54行,我的是<localRepository>F:/MavenRepository</localRepository>,F盘要先有这个文件夹
    Java 8 lambda Stream list to Map key 重复 value合并到Collection
    BufferedReader.readLine()读取文件
  • 原文地址:https://www.cnblogs.com/lingiu/p/3237317.html
Copyright © 2011-2022 走看看