在 Java 中比较字符串的最快方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3805601/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the quickest way to compare strings in Java?
提问by Mediator
What's the quickest to compare two strings in Java?
在 Java 中比较两个字符串最快的是什么?
Is there something faster than equals?
有什么比等于更快的吗?
EDIT: I can not help much to clarify the problem.
编辑:我无法帮助澄清这个问题。
I have two String which are sorted alphabetically and EXACTLY the same size
我有两个按字母顺序排序且大小完全相同的字符串
Example: abbcee and abcdee
示例:abbcee 和 abcdee
Strings can be long up to 30 characters
字符串最长可达 30 个字符
采纳答案by BalusC
I don't expect that SunOracle hasn't already optimized the standard String#equals()
to the max. So, I expect it to be already the quickest way. Peek a bit round in its source if you want to learn how they implemented it. Here's an extract:
我不认为SunOracle 还没有将标准优化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;
}
回答by oyo
回答by mikera
As always, you will need to benchmark for your application / environment. And unless you have already profiled and idetified this as a performance bottleneck, it's probably not going to matter ("premature optimization is the root of all evil").
与往常一样,您需要针对您的应用程序/环境进行基准测试。除非您已经将此作为性能瓶颈进行了分析和识别,否则这可能无关紧要(“过早的优化是万恶之源”)。
Having said that:
话说回来:
a.equals(b) is really fastfor Strings. It's probably one of the most tightly optimized pieces of code in the Java platform. I'd be very surprised if you can find any faster way of comparing two arbitrary strings.
a.equals(b)对于字符串来说真的很快。它可能是 Java 平台中最严格优化的代码片段之一。如果您能找到任何更快的方法来比较两个任意字符串,我会感到非常惊讶。
There are special caseswhere you can cheat and use (a==b)safely, e.g. if you know that both Strings are interned(and therefore value identity implies object identity). In that case it may be slightly faster than a.equals(b) - but again this depends on compiler/JVM implementation. And it's very easy to shoot yourself in the foot if you don't know what you are doing.....
在某些特殊情况下,您可以安全地作弊并使用 (a==b),例如,如果您知道两个字符串都被插入(因此值标识意味着对象标识)。在这种情况下,它可能比 a.equals(b) 稍快 - 但这同样取决于编译器/JVM 实现。如果您不知道自己在做什么,很容易将自己射中脚......
回答by user207421
Ifyou can show that it's a significant bottleneck, which would surprise me, you could try
如果你能证明这是一个重要的瓶颈,这会让我感到惊讶,你可以尝试
s1.hashCode() == s2.hashCode() && s1.equals(s2)
It might be a bit faster. It mightn't.
可能会快一些。可能不会。
回答by Stephan
Compare Strings of same length faster using the hashcode:
使用哈希码更快地比较相同长度的字符串:
public static boolean equals(final String s1, final String s2) {
return s1 != null && s2 != null && s1.hashCode() == s2.hashCode()
&& s1.equals(s2);
}
You can test it, my results are for 4000000 compare operations including identical, equal and different strings:
你可以测试一下,我的结果是 4000000 次比较操作,包括相同、相等和不同的字符串:
String.equals(String): 177081939
equals(String, String): 44153608
Note:Calculating the hashCode of a new string object takes some computation time and afterwards the hashCode is stored in the object. So my suggested improvement will only be faster than the default compare if string objects are reused. In my application I am using String constants and store strings in collections. Multiple comparisons of strings using my method are actually faster for me, but it may not be in general.
注意:计算新字符串对象的 hashCode 需要一些计算时间,然后将 hashCode 存储在对象中。因此,如果重用字符串对象,我建议的改进只会比默认比较快。在我的应用程序中,我使用字符串常量并将字符串存储在集合中。使用我的方法对字符串进行多重比较实际上对我来说更快,但一般情况下可能不是这样。
If the method is used with new strings all the time like compare("a", "b")
, it won't be an improvement.
如果该方法一直与新字符串一起使用,例如compare("a", "b")
,则不会有改进。
So the fastest way of comparing strings depends on:
所以比较字符串的最快方法取决于:
- Whether your string objects are reused (like from a collection) or are always new (like from an input stream)
- Whether your strings have different lengths
- Whether your strings differ at the start or the end of the string
- Your programming style, how much constants are used
- Your use of String.intern()
- 你的字符串对象是被重用的(比如来自一个集合)还是总是新的(比如来自输入流)
- 您的字符串是否有不同的长度
- 您的字符串在字符串的开头或结尾是否不同
- 您的编程风格,使用了多少常量
- 你对 String.intern() 的使用
Ignoring those facts, the majority of all programs will be fine with String.equals().
忽略这些事实,大多数程序都可以使用 String.equals()。
回答by ungalcrys
I had tries different combinations for string comparison (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);
I used strings of 40 chars length, in 10000000000L iterations and before any iteration I reinitialized the strings.
我使用了 40 个字符长度的字符串,在 10000000000L 次迭代中并且在任何迭代之前我重新初始化了字符串。
for equal stings I got:
对于同样的刺痛,我得到了:
equal: 2873 milis ???
equal: 21386 milis
equal: 7181 milis
equal: 2710 milis ???
for same size strings but last char different I got:
对于相同大小的字符串,但最后一个字符不同,我得到了:
different: 3011 milis
different: 23415 milis
different: 6924 milis
different: 2791 milis
for different sizes, almost same strings but one char added at the end for s2:
对于不同的大小,几乎相同的字符串,但在 s2 的末尾添加了一个字符:
different size: 3167 milis
different size: 5188 milis
different size: 6902 milis
different size: 2951 milis
seems to me it is best to use first a string.length() comparison before equals().
在我看来,最好在 equals() 之前先使用 string.length() 比较。
But this will not matter almost at all because this is the case where I have 10^10 string comparisons with 40 chars length and what is bizarre for me is the case where for equal strings I have a better speed when I compare the string length first.
但这几乎一点都不重要,因为在这种情况下,我有 10^10 个字符串与 40 个字符长度的比较,而对我来说奇怪的是,对于相等的字符串,当我首先比较字符串长度时,我有更好的速度.
回答by Flow
Simple answer
简单的回答
I'm pretty sure (this answer has some references) and it's very likely that the JIT will have an intrinsic for String#equals
, which means it would be able to replace the call with specially crafted machine code for the architecture your JVM is currently running on.
我很确定(这个答案有一些参考),而且 JIT 很可能有一个内在的 for String#equals
,这意味着它能够用为您的 JVM 当前运行的架构特制的机器代码替换调用。