public static void a(){
long starTime = new Date().getTime();
String string = new String();
for(int i=0;i<50000;i++){
string = string + i;
}
long endTime = new Date().getTime();
System.out.println("“+”号花费时间:"+(endTime - starTime));
}
这种方式花费的时间在6800毫秒左右。(由于机器性能不同,执行的时间也会有所差异。为了保证实验结果的正确性,请都在同一台机器上运行。)
public static void b(){
long starTime = new Date().getTime();
String string = new String();
for(int i=0;i<50000;i++){
string += i;
}
long endTime = new Date().getTime();
System.out.println("“+=”号花费时间:"+(endTime - starTime));
}
这种方式花费的时间大致与“+”号拼接相同,也在6800毫秒左右。如果有对python比较熟悉的,可以分别运行看一下。
public static void e(){
long starTime = new Date().getTime();
String string = new String();
for(int i=0;i<50000;i++){
string = string.concat(String.valueOf(i));
}
long endTime = new Date().getTime();
System.out.println("concat花费时间:"+(endTime - starTime));
}
这种方式花费的时间在2400毫秒左右。
public static void c(){
long starTime = new Date().getTime();
String string = new String();
StringBuffer stringb = new StringBuffer();
for(int i=0;i<50000;i++){
stringb = stringb.append(i);
}
string = string + stringb;
long endTime = new Date().getTime();
System.out.println("StringBuffer花费时间:"+(endTime - starTime));
}
这种方式花费的时间在37毫秒左右。
public static void d(){
long starTime = new Date().getTime();
String string = new String();
StringBuilder stringb = new StringBuilder();
for(int i=0;i<50000;i++){
stringb = stringb.append(i);
}
string = string + stringb;
long endTime = new Date().getTime();
System.out.println("StringBuilder花费时间:"+(endTime - starTime));
}
这种方式花费的时间也在37毫秒左右。由于5万次拼接对于StringBuffer和StringBuilder来说没什么区别,所以我把执行次数增加到了500万次。在500万次的执行中StringBuffer花费大约627毫秒;StringBuilder花费大约418毫秒。
这里我需要说明一点,我的实验环境都是在单线程情况下进行的。如果在多线程中StringBuilder的速度要明显优于StringBuffer。原因就在于StringBuffer内部的实现都加上了synchronized关键字,保证了线程安全的同时也因此降低了效率。下面是StringBuffer和StringBuffer拼接实现源码:
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
public static void d(){
long starTime = new Date().getTime();
String string = new String();
StringBuilder stringb = new StringBuilder();
for(int i=0;i<50000;i++){
stringb = stringb.append(i);
}
string = string + stringb;
long endTime = new Date().getTime();
System.out.println("StringBuilder花费时间:"+(endTime - starTime));
}
通过上面的源码我们可以发现,concat方法通过确认两个字符串中字符的个数新建一个字符数组。
public static void a(){
long starTime = new Date().getTime();
String string = new String();
for(int i=0;i<50000;i++){
StringBuilder sb = new StringBuilder();
sb.append(string).append(String.valueOf(i));
string = sb.toString();
}
long endTime = new Date().getTime();
System.out.println("“+”号底层替换花费时间:"+(endTime - starTime));
}
这段代码花费了9000毫秒左右。而且在大量的拼接过程中会反复的创建StringBuilder对象。
答案:当然不是。
public static void a(){
long starTime = new Date().getTime();
for(int i=0;i<5000000;i++){
String string = "Hua" + "PL";
}
long endTime = new Date().getTime();
System.out.println("“+”号花费时间:"+(endTime - starTime));
}
public static void d(){
long starTime = new Date().getTime();
for(int i=0;i<5000000;i++){
StringBuilder string = new StringBuilder("Hua");
string = string.append("PL");
}
long endTime = new Date().getTime();
System.out.println("StringBuilder花费时间:"+(endTime - starTime));
}
这种方式的拼接,“+”号方式只用了10毫秒;而StringBuilder用了314毫秒。