String str = “”;
for (int i = 0; i < 1000000; i++) {
str += i;
}
System.out.println(“String 耗时:” + (System.currentTimeMillis() - startTime) + “毫秒”);
1.2 StringBuilder
long startTime = System.currentTimeMillis();
StringBuilder str = new StringBuilder();
for (int i = 0; i < 1000000; i++) {
str.append(i);
}
System.out.println(“StringBuilder 耗时” + (System.currentTimeMillis() - startTime) + “毫秒”);
1.3 StringBuffer
long startTime = System.currentTimeMillis();
StringBuffer str = new StringBuffer();
for (int i = 0; i < 1000000; i++) {
str.append(i);
}
System.out.println(“StringBuffer 耗时” + (System.currentTimeMillis() - startTime) + “毫秒”);
综上,分别使用了 String
、StringBuilder
、StringBuffer
,做字符串链接操作(100个、1000个、1万个、10万个、100万个),记录每种方式的耗时。最终汇总图表如下;
从上图可以得出以下结论;
String
字符串链接是耗时的,尤其数据量大的时候,简直没法使用了。这是做实验,基本也不会有人这么干!StringBuilder
、StringBuffer
,因为没有发生多线程竞争也就没有🔒锁升级,所以两个类耗时几乎相同,当然在单线程下更推荐使用StringBuilder
。
2. StringBuilder 比 String 快, 为什么?
String str = “”;
for (int i = 0; i < 10000; i++) {
str += i;
}
这段代码就是三种字符串拼接方式,最慢的一种。不是说这种+
加的符号,会被优化成 StringBuilder
吗,那怎么还慢?
确实会被JVM编译期优化,但优化成什么样子了呢,先看下字节码指令;javap -c ApiTest.class
一看指令码,这不是在循环里(if_icmpgt)给我 new
了 StringBuilder
了吗,怎么还这么慢呢?再仔细看,其实你会发现,这new是在循环里吗呀,我们把这段代码写出来再看看;
String str = “”;
for (int i = 0; i < 10000; i++) {
str = new StringBuilder().append(str