java – 为什么“.concat(String)”比“”快得多?
|
参见英文答案 >
String concatenation: concat() vs “+” operator11
for(int i = 0; i < 100000000L; i++)
{
String str2 = str + str;
}
到“string”.concat(“string”): for(int i = 0; i < 100000000L; i++)
{
String str2 = str.concat(str);
}
其中str ==“string”. 我得到的输出与此一致,尽管平均差异通常更接近于61纳秒:
这表明即使循环和赋值到一个新的字符串,.concat比二分之二更快.当我使用一个更长的字符串(str ==“这是非常长的真正非常长的字符串”),它的速度比三分之一快.这是特别奇怪的,因为如果.concat更快,不应该编译成.concat? 我的主要问题是:为什么.concat更快? 完整的代码,以防您想要运行它并进行实验: public class TimeCompare
{
public static void main(String[] args)
{
final long times = 100000000L;
String str = "String";
long start1 = System.nanoTime();
for(int i = 0; i < times; i++)
{
String str2 = str + str;
}
long end1 = System.nanoTime();
long time1 = end1 - start1;
System.out.println((double)(time1) / times);
System.out.println();
long start2 = System.nanoTime();
for(int i = 0; i < times; i++)
{
String str2 = str.concat(str);
}
long end2 = System.nanoTime();
long time2 = end2 - start2;
System.out.println((double)(time2) / times);
System.out.println();
System.out.println(".concat is faster than "+" by " + ((double)(time1 - time2) / times) + " nanoseconds");
}
}
解决方法以下是concat的源代码:public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value,len + otherLen);
str.getChars(buf,len);
return new String(buf,true);
}
“string”“string”编译为新的StringBuilder().append(“string”).append(“string”).toString().1 append的源代码使用其超类’,AbstractStringBuilder, public AbstractStringBuilder append(String str) {
if (str == null) str = "null";
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0,len,value,count);
count += len;
return this;
}
用方法的源代替方法调用后: /////////////////concat
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = ((Object)value.getClass() == (Object)Object[].class)
? (T[]) new Object[len + otherLen]
: (T[]) Array.newInstance(value.getClass().getComponentType(),len + otherLen);
System.arraycopy(value,buf,Math.min(value.length,len + otherLen));
System.arraycopy(str.value,str.value.length);
return new String(buf,true);
///////////////append
if (str == null) str = "null";
int len = str.length();
if (value.length + len - value.length > 0)
{
int newCapacity = value.length * 2 + 2;
if (newCapacity - value.length + len < 0)
newCapacity = value.length + len;
if (newCapacity < 0) {
if (value.length + len < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
value = ((Object)value.getClass() == (Object)Object[].class)
? (T[]) new Object[newCapacity]
: (T[]) Array.newInstance(value.getClass().getComponentType(),newCapacity);
System.arraycopy(value,(value.length <= newCapacity) ? value.length : newCapacity;
}
if (0 < 0) {
throw new StringIndexOutOfBoundsException(0);
}
if (len > str.value.length) {
throw new StringIndexOutOfBoundsException(len);
}
if (0 > len) {
throw new StringIndexOutOfBoundsException(len - 0);
}
System.arraycopy(str.value,value.length,len - 0);
count += len;
return this;
删除不会使用给定字符串执行的代码,并删除它们之间相同的代码: //////////////concat int len = value.length; len + otherLen System.arraycopy(value,len + otherLen)); System.arraycopy(str.value,str.value.length); this.value = value; /////////////////append if(value.length + len - value.length > 0) int newCapacity = value.length * 2 + 2; if(newCapacity - value.length + len < 0) if(newCapacity < 0) System.arraycopy(value,(value.length <= newCapacity) ? value.length : newCapacity); if(0 < 0) if(len > str.value.length) if(0 > len) System.arraycopy(str.value,len - 0); count += len; 在计算所有操作和删除concat和append之间相同的操作之后: concat -------- int assignment: 0 int +/-: 0 int comparison: 0 char[] assignment: 1 arraycopy: 0 int *: 0 append -------- int assignment: 1 int +/-: 5 int comparison: 6 char[] assignment: 0 arraycopy: 0 int *: 1 您可以看到,在几乎所有情况下,一个concat都将比一个附加更快,并编译为两个追加和一个toString. [1]:A: String concatenation: concat() vs + operator (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
