Какой самый быстрый способ сравнить строки в Java?
Что самое быстрое сравнение двух строк в Java?
Есть ли что-то быстрее, чем равное?
EDIT:
Я не могу помочь, чтобы прояснить проблему.
У меня есть две строки, которые сортируются в алфавитном порядке и ТОЧНО одинакового размера
Пример: abbcee и abcdee
Строки могут быть длинными до 30 символов
Ответы
Ответ 1
Я не ожидаю, что 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;
}
Ответ 2
Сравнивать строки той же длины быстрее с помощью hashcode:
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
Примечание. Вычисление хэш-кода нового строкового объекта занимает некоторое время вычисления, а затем хэш-код сохраняется в объекте. Поэтому мое рекомендуемое улучшение будет только быстрее, чем сравнение по умолчанию, если строковые объекты повторно используются. В моем приложении я использую константы String и сохраняю строки в коллекциях. Множество сравнений строк, использующих мой метод, на самом деле быстрее для меня, но это может быть не вообще.
Если метод используется с новыми строками все время, например compare("a", "b")
, это не будет улучшением.
Таким образом, самый быстрый способ сравнения строк зависит от:
- Повторяются ли ваши строковые объекты (например, из коллекции) или всегда являются новыми (например, из потока ввода)
- Будут ли ваши строки иметь разную длину.
- Различаются ли ваши строки в начале или в конце строки.
- Ваш стиль программирования, сколько констант используется
- Использование String.intern()
Игнорируя эти факты, большинство всех программ будут в порядке с String.equals().
Ответ 3
Я попытался использовать разные комбинации для сравнения строк (здесь):
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 ???
для строк того же размера, но последний char другой я получил:
different: 3011 milis
different: 23415 milis
different: 6924 milis
different: 2791 milis
для разных размеров, почти одинаковые строки, но один char добавлен в конец для s2:
different size: 3167 milis
different size: 5188 milis
different size: 6902 milis
different size: 2951 milis
мне кажется, лучше всего сначала использовать сравнение string.length() перед equals().
Но это не имеет значения почти для всех, потому что это тот случай, когда у меня есть 10 ^ 10 строк сравнения с длиной в 40 символов, и что для меня странно, это тот случай, когда для равных строк у меня есть более высокая скорость, когда я сравниваю длина строки сначала.
Ответ 4
Это зависит от того, что вам нужно. Я думаю, что equals() действительно оптимизирован, но, возможно, вам нужно что-то еще быстрее, чем equals(). Взгляните на этот пост.
Ответ 5
Если вы можете показать, что это значительное узкое место, которое меня удивит, вы можете попробовать
s1.hashCode() == s2.hashCode() && s1.equals(s2)
Это может быть немного быстрее. Это может и не быть.
Ответ 6
Как всегда, вам нужно будет ориентироваться на ваше приложение/среду. И если вы уже не профилировали и не идентифицировали это как узкое место в производительности, это, вероятно, не имеет значения ( "преждевременная оптимизация - это корень всего зла" ).
Сказав, что:
a.equals(b) очень быстро для строк. Это, вероятно, одна из наиболее сильно оптимизированных частей кода на платформе Java. Я был бы очень удивлен, если бы вы могли найти более быстрый способ сравнения двух произвольных строк.
Существуют специальные случаи, где вы можете обманывать и использовать (a == b) безопасно, например. если вы знаете, что обе строки интернированы (и поэтому значение identity означает идентификатор объекта). В этом случае он может быть немного быстрее, чем a.equals(b), но опять же это зависит от реализации компилятора /JVM. И очень легко стрелять в ногу, если вы не знаете, что делаете.....
Ответ 7
Простой ответ
String.equals(Object)
Я уверен (этот ответ содержит несколько ссылок), и очень вероятно, что JIT будет иметь встроенный для String#equals
, что означает, что это будет способный заменить вызов с помощью специально созданного машинного кода для архитектуры, в которой в настоящее время работает JVM.