String, StringBuffer, StringBuilder拼接字符串的执行效率比较

关于String, StringBuffer, StringBuilder在拼接字符串时的执行效率,网上已经有很多文章介绍了,这里我实际测了一下,可总结为:

String.concat  > StringBuilder > StringBuffer > String+=

注:

(1)此处的String+=不是在编译期

(2)StringBuilder > StringBuffer这个在单线程下也不是绝对的

实际代码:

package string;
/**
 * 
 * String和StringBuffer和StringBuilder的执行效率比较
 * 
 * 
 */
public class StringBuffer_VS_String_Efficiency {
	static int times = 20000;//循环次数
//	static int times = 200000;//循环次数
//	static int times = 2000000;//循环次数
	/**
	 * 
	 * String+=
	 */
	public static void StringTest(String s){
		String str = "";
		long startTime = System.currentTimeMillis();
		for(int i=0;i<times/100;i++){
			str += s;
		}
		long endTime = System.currentTimeMillis();
		System.out.println("String+=所用的时间:"+ (endTime - startTime));
	}
	/**
	 * String+=的实际执行过程(jdk1.5以上版本会做优化)
	 * str += "here";可以等同于
	 * StringBuilder sb = new StringBuilder(str);
	 * sb.append("here");
	 * str = sb.toString();
	 */
	public static void StringTest2(String s){
		String str = "";
		long startTime = System.currentTimeMillis();
		for(int i=0;i<times/100;i++){
			StringBuilder sb = new StringBuilder(str);
			sb.append(s);
			str = sb.toString();
		}
		long endTime = System.currentTimeMillis();
		System.out.println("String+=的实际执行过程所用的时间:"+ (endTime - startTime));
	}
	
	/**
	 * String.concat()
	 * 是利用Char[]拼接起来的(新建String对象)
	 */
	public static void StringConcatTest(String s){
		String str = "";
		long startTime = System.currentTimeMillis();
		for(int i=0;i<times;i++){
			str.concat(s);
		}
		long endTime = System.currentTimeMillis();
		System.out.println("String.concat方法所用的时间:"+ (endTime - startTime));
	}
	
	/**
	 * StringBuffer
	 * append方法也是利用Char[]拼接起来的(没有新建String对象,
	 * 每次扩容至(value.length + 1) * 2)
	 */
	public static void StringBufferTest(String s){
		StringBuffer sb = new StringBuffer();
		long startTime = System.currentTimeMillis();
		for(int i=0;i<times;i++){
			sb.append(s);
		}
		String s1 = sb.toString();
		long endTime = System.currentTimeMillis();
		System.out.println("StringBuffer所用的时间:"+ (endTime - startTime));
	}
	
	/**
	 * StringBuilder
	 * append方法和StringBuffer中是一样的内容
	 */
	public static void StringBuilderTest(String s){
		StringBuilder sb = new StringBuilder();
		long startTime = System.currentTimeMillis();
		for(int i=0;i<times;i++){
			sb.append(s);
		}
		String s1 = sb.toString();
		long endTime = System.currentTimeMillis();
		System.out.println("StringBuilder所用的时间:"+ (endTime - startTime));
	}
	
	public static void main(String[] args){
		String s = "asdfghhjkqwerty";
		StringTest(s);
		StringTest2(s);
		StringConcatTest(s);
		StringBufferTest(s);
		StringBuilderTest(s);
	}
	
}

注:由于循环次数太大,而String +=的执行时间太慢,所以让String +=的循环次数改为了times/100,就这样,起执行时间还是比StringBuffer, StringBuilder要长的多

运行结果:

1. times = 20000;//循环次数  时:

String+=所用的时间:0
String+=的实际执行过程所用的时间:0
String.concat方法所用的时间:0
StringBuffer所用的时间:0
StringBuilder所用的时间:16

2. times = 200000;//循环次数  时:

String+=所用的时间:78
String+=的实际执行过程所用的时间:62
String.concat方法所用的时间:16
StringBuffer所用的时间:31
StringBuilder所用的时间:47

3. times = 2000000;//循环次数  时:

String+=所用的时间:10047
String+=的实际执行过程所用的时间:10171
String.concat方法所用的时间:125
StringBuffer所用的时间:391
StringBuilder所用的时间:266

 

结果分析:

(1)结果1中由于循环次数不算太大,String+=的循环次数也只是times/100,所以会出现string+=的执行时间为0,而在结果2,3中,即便是String+=循环的次数只有    StringBuilder 和StringBuffer的百分之一,其执行效率也是远不如后二者;

(2)综合1,2中的结果来看,在循环次数不算太大的情况下,执行效率:StringBuilder < StringBuffer;

          而在结果3中, 执行效率:StringBuilder > StringBuffer; 所以单线程下StringBuilder 和StringBuffer的执行效率也不是绝对确定的。
(3)综合以上结果中,String.concat()方法的执行效率是最高的,但是由于这个方法中每次都是创建一个新的字符串,丢弃原来的字符串,所以垃圾收集的压力会较大。

          其源代码如下:

 public String concat(String s)
    {
        int i = s.length();
        if(i == 0)
        {
            return this;
        } else
        {
            char ac[] = new char[count + i];
            getChars(0, count, ac, 0);
            s.getChars(0, i, ac, count);
            return new String(0, count + i, ac);
        }
    }

(4)关于StringBuilder 和StringBuffer的执行效率的比较,为了不受其他方法影响,在main()方法中注释掉了其他方法,又单独比较了下这两个方法
 

public static void main(String[] args){
		String s = "asdfghhjkqwerty";
//		StringTest(s);
//		StringTest2(s);
//		StringConcatTest(s);
		StringBufferTest(s);
		StringBuilderTest(s);
	}

结果发现在循环次数分别为万、十万、百万这几个数量级上,两者的执行效率还是不绝对确定,每次执行结果都可能不一样,结果规律是:循环次数越大,StringBuilder体现出的效率就越高,StringBuilder >StringBuffer可能性越大。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值