java字符串连接性能分析

字符串连接一向是比较常用的 ,异常日志输出或者是文字的组装等等,因此需要去思考选择哪种方法性能最高
假设我们需要连接strA 和 strB 常用的几种字符串组装方式如下:

1.String.format("%s%s",strA,strB)
2.srtA + strB
3.strA.concat(strB)
4.new StringBuilder(strA).append(strB)
5.new StringBuffer(strA).appedn(strB)

这几种有什么差别,
1、String.format 通过匹配占位符的方式,往字符串里面插入参数值,而这种实现方法比一般的连接字符串方式耗时更长
不过有时候format这种方式的可读性更好,通过占位符还可以指定插入的参数类型

2、+操作符连接字符串实际上是调用StringBuilder.append,但是通过+连接的每个字符串都是一个新的对象,
类似String result = "Hello " + "world"; 实际上为了得到一个字符串而创建了3个String对象,剩余的2个对象就交给了GC,
但是如果遇到更多的字符串连接,或者是循环调用,使用+操作符进行连接会导致大量的String对象让GC去处理
 //以下两者是等价的
s = i + ""
s = String.valueOf(i);

//以下两者也是等价的
s = "abc" + i;
s = new StringBuilder("abc").append(i).toString();

3、contat源码实现则是通过拷贝当前字符串的char[]成员变量,然后进行扩容,之后再将拼接字符串拷贝进去,开销挺大
每次操作都会产生一个新的String对象

4、StringBuilder只新建了一个对象,通过查看源码可以看到内部有一个char[]类型的动态数组来存储字符串。
很显然StringBuilder在开销方面更小

5、StringBuffer则是线程安全的StringBuilder


写个简单的程序对比一下字符串连接的性能:
/*
 * Copyright (C) 2009-2016 Hangzhou 2Dfire Technology Co., Ltd.All rights reserved
 */
package com.twofire.wechat.service;

/**
 * StringCombineCostTimeTest
 *
 * @author shinan
 * @since 2017-03-03
 */
public class StringCombineCostTimeTest {
    private static String request = "request";
    private static String result = "result";


    public static void combineTimeCost(int count) {
        combineByStringFormat(count);
        combineByStringPlusOperator(count);
        combineByStringBuilder(count);
        combineByStringConcat(count);
        System.out.println("---------------------------------------");
    }

    public static void combineByStringFormat(int count) {
        long start = System.currentTimeMillis();
        for (int i = 0; i< count;i++) {
            String combineResult =  String.format("request = %s, result = %s", request, result);
        }
        long end = System.currentTimeMillis();
        long cost = end - start;
        System.out.println(count + " combine String.format cost : " + cost);
    }

    public static void combineByStringPlusOperator(int count) {
        long start = System.currentTimeMillis();
        for (int i = 0; i< count;i++) {
            String combineResult = "request = " + request + " result = " + result;
        }
        long end = System.currentTimeMillis();
        long cost = end - start;
        System.out.println(count + " combine String add cost : " + cost);
    }

    public static void combineByStringBuilder(int count) {
        long start = System.currentTimeMillis();
        for (int i = 0; i< count;i++) {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("request = ").append(request).append(" result = ")
                    .append(result);
        }
        long end = System.currentTimeMillis();
        long cost = end - start;
        System.out.println(count + " combine StringBuilder cost : " + cost);
    }

    public static void combineByStringConcat(int count) {
        long start = System.currentTimeMillis();
        for (int i = 0; i< count;i++) {
            String str = "";
            str.concat("request = ").concat(request).concat(" result = ").concat(result);
        }
        long end = System.currentTimeMillis();
        long cost = end - start;
        System.out.println(count + " combine Concat cost : " + cost);
    }

    public static void main(String[] args){
        combineTimeCost(1000000);
        combineTimeCost(1000000);
        combineTimeCost(1000000);

    }
}



耗时统计:
String.format耗时最长
concat中等,+和StringBuilder较为接近

即时在做最简单的拼接时,如果我们不想创建StringBuffer或StringBuilder实例的时候可以使用concat。但是对于大量的字符串拼接操作,我们就不应该使用concat,因为concat会降低程序的性能,消耗cpu。因此,在不考虑线程安全和同步的情况下,为了获得最高的性能,我们应尽量使用StringBuilder
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值