为什么String.equalsIgnoreCase太慢了
我在面试中遇到了一个问题,写出一种方法来检查类似的词语,而不考虑字符个案。
我通过使用每对字符的ASCII值的差异来回答它。 但在家里,当我在String.class中实际执行它时,我感到不安 - 为什么它以这种方式实现!
我试图在内置和我的自定义方法之间进行比较,
public class EqualsIgnoreCase {
public static void main(String[] args) {
String str1 = "Srimant @$ Sahu 959s";
String str2 = "sriMaNt @$ sAhu 959s";
System.out.println("Avg millisecs with inbuilt () - " + averageOfTenForInbuilt(str1, str2));
System.out.println("nAvg millisecs with custom () - " + averageOfTenForCustom(str1, str2));
}
public static int averageOfTenForInbuilt(String str1, String str2) {
int avg = 0;
for (int itr = 0; itr < 10; itr++) {
long start1 = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
str1.equalsIgnoreCase(str2);
}
avg += System.currentTimeMillis() - start1;
}
return avg / 10;
}
public static int averageOfTenForCustom(String str1, String str2) {
int avg = 0;
for (int itr = 0; itr < 10; itr++) {
long start2 = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
isEqualsIgnoreCase(str1, str2);
}
avg += System.currentTimeMillis() - start2;
}
return avg / 10;
}
public static boolean isEqualsIgnoreCase(String str1, String str2) {
int length = str1.length();
if (str2.length() != length) {
return false;
}
for (int i = 0; i < length; i++) {
char ch1 = str1.charAt(i);
char ch2 = str2.charAt(i);
int val = Math.abs(ch1 - ch2);
if (val != 0) {
if (isInAlphabetsRange(ch1, ch2)) {
if (val != 32) {
return false;
}
} else {
return false;
}
}
}
return true;
}
public static boolean isInAlphabetsRange(char ch1, char ch2) {
return (((ch1 <= 122 && ch1 >= 97) || (ch1 <= 90 && ch1 >= 65)) && ((ch2 <= 122 && ch2 >= 97) || (ch2 <= 90 && ch2 >= 65)));
}
}
输出 -
平均毫秒与内置() - 14
自定义()的平均毫秒数 - 5
我发现内置方法正在提高效率,因为有很多检查和方法调用。 这种实施背后有什么具体原因吗? 或者我在逻辑中错过了什么?
任何建议,将衷心感谢!
你的例程只处理ASCII字符。 系统处理所有的unicode字符。
考虑下面的例子:
public class Test {
public static void main(String[] args) {
System.out.println((int) 'ě'); // => 283
System.out.println((int) 'Ě'); // => 282
}
}
你的方法在很多方面都不正确。 例如,它认为“!” 等于“B”,“B”等于“1”,但“!” 不等于“1”(所以它不是传递的,因为我们期望等于方法)。
是的,为该方法编写不正确的实现更容易,既快速又简单。 一个公平的挑战是编写一个正确的,即正确处理JDK实现所做的所有参数。
您可能还想看看如何在Java中编写正确的微基准测试? 以获得更可靠的性能测量。
这可能不是唯一的原因,但事实上,您的解决方案并不适用于所有可能的字符串,这绝对是一个因素。
有一些(恼人的)区域设置,其中两个字符可能具有相同的大写但不是相同的小写。 出于这个原因,为了工作(大部分时间,请参见土耳其语),规范实现必须比较字符串char-for-char在它们的较低和较大的情况下。
在99%的时间内,你的实现可能是完美的,特别是如果你只需要处理英文语言环境,但核心库实现可能不会做出这样的假设。
链接地址: http://www.djcxy.com/p/39567.html