String StringBuffer StringBuilder的效率

前两天面试有问,string跟stringbuffer还有stringbuilder的效率以及区别问题

回来写了个测试程序:

测试实例

这是main方法

public static void main(String[] args) {
		long time=System.currentTimeMillis();
	
		do1();
		long time1=System.currentTimeMillis();
		System.out.println("string:"+(time1-time));
		do2();
		long time2=System.currentTimeMillis();
		System.out.println("stringbuffer:"+(time2-time1));
		do3();
		long time3=System.currentTimeMillis();
		System.out.println("stringbuilder:"+(time3-time2));


	}

这是do1(string)

private static void do1() {
		String a="";
		for (int i = 0; i <5; i++) {
			a+="a"+"b"+"c"+"d";
			
		}
		
	}

do2(stringbuffer)

private static void do2() {
		StringBuffer a=new StringBuffer();
		for (int i = 0; i <5; i++) {
			a.append("a");
			a.append("b");
			a.append("c");
			a.append("d");		
		}
	}

do3(stringbuilder)

private static void do3() {
		StringBuilder a=new StringBuilder();
		for (int i = 0; i <5; i++) {
			a.append("a");
			a.append("b");
			a.append("c");
			a.append("d");		
		}
	}

 

先运行一下,结果如下。

循环次数太小,再把次数上调到一百试试。

然后一千。

还是不怎么明显,这次一万应该差不多了。

十万:

二十万:

小结

string的效率明显低下。string的拼接每次相加其实都相当于new了一个新对象,从常量池里面拿出来后新建对象。然后一直占着内存等待gc回收,但是gc回收机制不是即时的,这就导致了大量资源占着从而效率低下。

stringbuffer和stringbuilder每次操作的都是同一个对象

String采用连接运算符(+)效率低下,都是循环、大批量数据情况造成的,每做一次"+"就产生个StringBuilder对象,然后append后就扔掉。下次循环再到达时重新产生个StringBuilder对象,然后append字符串,如此循环直至结束。如果我们直接采用StringBuilder对象进行append的话,我们可以节省创建和销毁对象的时间。如果只是简单的字面量拼接或者很少的字符串拼接,性能都是差不多的。

关于stringbuilder和stringbuffer的选择

String是不可变类,所以是线程安全的。

1、所有不可变类都是线程安全的,线程安全的类不一定是不可变类,如StringBuffer是可变类,靠锁实现线程安全。

2、StringBuffer方法上都加了synchronized,StringBuilder没有,StringBuilder在多线程情况下是会出现问题,但是线程安全 线程非安全 指的是你业务环境需要线程安全考虑不考虑。多并发网络编程这块会考虑这些。

在Java语言中,线程是一种特殊的对象,它必须由Thread类或其子(孙)类来创建。通常有两种方法来创建线程:其一,使用型构为Thread(Runnable)的构造子将一个实现了Runnable接口的对象包装成一个线程。其二,从Thread类派生出子类并重写run方法,使用该子类创建的对象即为线程。值得注意的是Thread类已经实现了Runnable接口,因此,任何一个线程均有它的run方法,而run方法中包含了线程所要运行的代码。线程的活动由一组方法来控制。Java语言支持多个线程的同时执行,并提供多线程之间的同步机制(关键字为synchronized)。

结论

如果字符串不需要频繁变动的话,三个选哪个都无所谓的。如果变动频繁选哪个,其实大部分string操作都是在单线程下进行的,如果有特殊需要再选用线程安全的stringbuffer,基本上可以直接用stringbuilder的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值