【发布时间】:2013-09-18 20:00:14
【问题描述】:
我正在查看java.lang.String 的源代码,并注意到equals method 不检查支持每个字符串的char[] 是否是同一个对象。这不会缩短比较时间吗?
此重写版本中包含的假设改进:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
/** Begin Optimization **/
if(v1==v2 && i==j){
return true;
}
/** End Optimization **/
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
我相信这会在两个字符串是使用String.substring 获得的情况下提高性能,甚至可能是实习字符串。
有人知道他们选择不以这种方式实施它是否有原因?
更新: 对于可能不太了解implementation of String 的任何人,除了字符串池之外,还有一些情况下,两个字符串对象可以具有相同的 char[] 值、int 偏移量、和 int 计数。
考虑以下代码:
String x = "I am a String, yo!";
String y = x.split(" ")[3];
String z = x.substring(7,14);
你最终会遇到这样的情况:
显然,字符串的值共享功能在 Java 7u6 中已被取消,以满足某些基准。因此,如果您通过使用 String.substring() 而不是字符串连接花时间让代码在适当的时间(或完全)运行,那么您就是 SOL。
【问题讨论】:
-
方法是比较每个字符。
-
可能没有意义,因为总是使用
clone()数组 -
它可能在 Java 7 之前的极少数情况下提高了性能——例如
foo.substring(i, j).equals(foo.substring(i, j))——但当字符串数组 not 相等时,它也会对更常见的情况进行额外检查,这似乎平均花费的时间可能比节省的时间多。参见例如this blog post. -
@SotiriosDelimanolis 我不是在问他们是否是 .equal();我在问它们是否是同一个对象。
-
@LouisWasserman 我会说这个优化和他的例子之间最重要的区别是,这将通过再运行 O(1) 行代码(1 或 2 次比较)来防止 O(n) 操作,取决于我们有多幸运);而他的示例仅阻止了 n=0 或 n=1(基本上)的 O(n) 操作。
标签: java string performance micro-optimization