比较Java中两个字符串最快的是什么?
有比平等更快的东西吗?
编辑: 我无法帮助澄清这个问题。
我有两个按字母顺序排序且完全相同的字符串
示例:abbcee和abcdee
字符串最长可达30个字符
答案 0 :(得分:31)
我不希望 Sun Oracle尚未将标准String#equals()
优化到最大值。所以,我希望它已经是最快捷的方式了。如果你想了解它们是如何实现的,请在它的源代码中查看一下。这是一个摘录:
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;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
答案 1 :(得分:24)
使用哈希码更快地比较相同长度的字符串:
public static boolean equals(final String s1, final String s2) {
return s1 != null && s2 != null && s1.hashCode() == s2.hashCode()
&& s1.equals(s2);
}
你可以测试它,我的结果是4000000比较操作,包括相同,相同和不同的字符串:
String.equals(String): 177081939
equals(String, String): 44153608
注意:计算新字符串对象的hashCode需要一些计算时间,然后hashCode存储在对象中。因此,如果重用字符串对象,我建议的改进只会比默认比较快。在我的应用程序中,我使用String常量并在集合中存储字符串。使用我的方法对字符串进行多次比较对我来说实际上更快,但它可能不是一般的。
如果该方法始终与compare("a", "b")
一起使用新字符串,则不会有任何改进。
因此,比较字符串的最快方法取决于:
忽略这些事实,大多数程序都可以使用String.equals()。
答案 2 :(得分:4)
我尝试了不同的字符串比较组合(code here):
1. s1.equals(s2)
2. s1.length() == s2.length() && s1.hashCode() == s2.hashCode() && s1.equals(s2)
3. s1.hashCode() == s2.hashCode() && s1.equals(s2);
4. s1.length() == s2.length() && s1.equals(s2);
我使用40个字符长度的字符串,在10000000000L次迭代中,在任何迭代之前我重新初始化字符串。
我得到了相同的咒语:
equal: 2873 milis ???
equal: 21386 milis
equal: 7181 milis
equal: 2710 milis ???
对于相同大小的字符串,但最后的字符不同,我得到了:
different: 3011 milis
different: 23415 milis
different: 6924 milis
different: 2791 milis
对于不同的大小,几乎相同的字符串,但最后为s2添加了一个char:
different size: 3167 milis
different size: 5188 milis
different size: 6902 milis
different size: 2951 milis
在我看来,最好先使用equals()之前的string.length()比较。
但这几乎没关系,因为这是我有10 ^ 10个字符串比较40个字符长度的情况,对我来说奇怪的是,对于相同的字符串我比较时有更好的速度首先是字符串长度。
答案 3 :(得分:3)
这取决于你的需要。我认为equals()确实是优化的,但也许你需要比equals()更快的东西。看看this post。
答案 4 :(得分:3)
如果你可以证明它是一个重大的瓶颈,这会让我感到惊讶,你可以尝试
s1.hashCode() == s2.hashCode() && s1.equals(s2)
可能会快一些。它可能不会。
答案 5 :(得分:1)
简单回答
我很确定(this answer has some references)并且JIT很可能具有String#equals
的固有内容,这意味着它可以用特制的机器代码替换该调用您的JVM当前正在运行的体系结构。
答案 6 :(得分:0)
与往常一样,您需要针对您的应用程序/环境进行基准测试。除非你已经描述并将其视为性能瓶颈,否则它可能无关紧要(“过早优化是所有邪恶的根源”)。
说完了:
对于Strings,特殊情况,您可以安全地欺骗和使用(a == b),例如如果你知道both Strings are interned(因此值身份意味着对象身份)。在这种情况下,它可能比a.equals(b)略快 - 但这又取决于编译器/ JVM的实现。如果你不知道自己在做什么,那就很容易在脚下射击.....