java字符串连接性能分析

来源:互联网 发布:美丽笨女人歌曲 知乎 编辑:程序博客网 时间:2024/06/13 23:49
字符串连接一向是比较常用的 ,异常日志输出或者是文字的组装等等,因此需要去思考选择哪种方法性能最高
假设我们需要连接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
原创粉丝点击