Coding测试

知识储备深度,决定测试深度!

循环中拼接String不同方法性能耗时对比

对比背景

  • Java中最常用的拼接字符串方法就是 + 或 +=,使用上简单方便。但如果拼接数量比较大,例如在循环中拼接字符串,可能会有性能问题;

测试数据

  • 循环100000次进行String拼接,对比+=和使用StringBuilder,StringBuffer。运行在JDK8,查看循环耗时时间

具体实现如下

  • 使用+=进行拼接String
@Test
    //使用+=进行拼接String
    public void testCase1(){
        String str = "";
        long startTime= System.currentTimeMillis();
        for (int i = 0;i< 100000;i++){
            str += i;
        }
        long endTime= System.currentTimeMillis();
        System.out.println(endTime-startTime);

    }
  • 使用StringBuilder
     //使用StringBuilder
    @Test
    public void testCase2(){
        StringBuilder stringBuilder = new StringBuilder();
        long startTime= System.currentTimeMillis();
        for (int i = 0 ; i< 100000;i++){
            stringBuilder.append(i);
        }
        long endTime= System.currentTimeMillis();
        System.out.println(endTime-startTime);
    }
  • 使用StringBuffer
//使用StringBuffer
    @Test
    public void testCase3(){
        StringBuffer str = new StringBuffer();
        long startTime= System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            str.append(i);
        }
        long endTime= System.currentTimeMillis();
        System.out.println(endTime-startTime);
    }
  • 执行结果对比

  • 使用+=进行拼接String耗时(单位:毫秒):18301

  • 使用StringBuilder耗时(单位:毫秒):5

  • 使用StringBuffer耗时(单位:毫秒):6

原理分析

  • 可以看到在上面的10w次循环拼接中,直接使用+=拼接的时间对比其他两个有近3600倍的差距,因为每次循环java都会自动创建一个StringBuilder用来做String拼接,然后转化为String赋值给str,造成了大量的对象创建开销,反编译代码如下

  • 而使用StringBuilder和StringBuffer的情况性能上就好太多了,如果对总的字符串长度有一个基本的预期,可以在new的时候指定capacity以节省当空间不够时扩容的开销。

  • StringBuffer作为线程安全类,在以前性能是比较差的,因此才有了非线程安全的StringBuilder,但JDK1.6以后由于java对synchronized锁做了优化(偏向锁→ 轻量级锁→ 重量级锁),StringBuffer性能有了极大提升,但习惯性的在没有并发情况下,还是使用StringBuilder

解决方案

当有大量字符串拼接需要时,尤其是在循环中,考虑使用StringBuilder或StringBuffer


更多测试技术分享、学习资源以及一些其他福利可关注公众号:【Coding测试】获取:

posted @ 2021-09-22 20:30  Coding测试  阅读(424)  评论(0编辑  收藏  举报