2013-12-02 4 views
1

Так я делаю некоторые исследования по самым быстрым на сравнении строк и нашел этот код:Комбинирование hashCode() и equals() выполняется быстрее?

if (s1.hashCode() == s2.hashCode() && s1.equals(s2)) 

Мой вопрос: Почему это быстрее? Причина в том, что я думаю, что требуется больше компьютерного цикла, чем просто говорить без & &.

+2

это быстрее, чем что? – Antoniossss

+1

, чем сказать if (s1.equals (s2)) –

+0

Быстрее ли сравнивать отпечатки пальцев или ДНК двух людей? – Mehrdad

ответ

16

строки Java кэшируют свои хэш-коды - так что если хэш-коды равны, строки очень вероятно, что будет равным. Полная проверка равенства может занять гораздо больше времени, если строки имеют одинаковую длину и отличаются только от самого конца. (. Реализация equals в String сначала проверяет длины, прежде чем он смотрит на фактических кодовых единицах)

С другой стороны, это требует хэш-код должен быть вычислен - если он еще не был вычислен, что будет O (n) в длине строки, тогда как две строки неравной длины могут быть сравнены для равенства очень быстро.

Так если вы знаете, что строки уже хэшируются и вы ожидаете там будет много строк с одинаковой длиной , это оптимизация - в противном случае это может сделать вещи медленнее. Однако я бы не использовал его в коде общего назначения, и я бы добавил комментарий, объясняющий причину этого.


И вы уже не знаете, что хэш-коды равны через какой-то другой механизм, в соответствии с комментарием SUPERCAT в поле ниже - я бы сказал, что это угол случай на угловом случае, хотя ,

+0

Хотя, если он не скрывался в вашем коде все время, шансы на хэширование ранее были довольно высокими, даже если вы не сделали этого, сделайте это. – cHao

+0

@ruakh: Струны в частности. Например, http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/String.java#String.hashCode%28%29. Некоторые другие классы почти наверняка тоже делают это ... т. Е. Это не JVM. – cHao

+0

@ruakh: Это деталь реализации в 'java.lang.String'. И это никогда не будет признано недействительным для 'String', поскольку строки неизменны в Java. –

1

s1.hashCode() == s2.hashCode() && s1.equals (s2) здесь, если левая сторона этого выражения неверна, что не будет оценивать правую сторону. Тогда это поможет немного быстро. Но не всегда.

+0

имеет смысл ..... – TheLostMind

+0

Но если они равны, обе половины выражения должны быть оценены, что будет медленнее. Я полагаю, вы могли бы использовать это, если бы ожидали, что подавляющее большинство сравнений будет равным, но это будет зависящим от реализации. –

+1

@BillHorvathII: проверка хеш-кода полезна только тогда, когда строка проверяется на равенство по отношению к другим строкам, которые имеют одинаковую длину и имеют длинный сопоставительный префикс, но тем не менее имеют разные значения хэш-функции. В большинстве программ такие ситуации будут встречаться редко, если они встречаются вообще, но в некоторых программах они могут возникать часто. Обратите внимание, однако, что многие случаи, когда такая оптимизация может быть полезной, могут быть еще более полезными, используя альтернативный метод хеширования строки вместо 'getHashCode()'. – supercat

2

Я не думаю, что это быстрее. Если бы это было, это было бы включено в реализацию String.equals. Обратите внимание, что первый вызов String.hashCode является дорогостоящим. Представьте, что вам нужны только String.equals, но вы вычисляете хэш на обеих строках. Скорее всего, это будет убийство.

+0

+1. 'String.equals', безусловно, может сказать, кэшированы ли хэш-коды обеих строк. – ruakh

+0

Это может быть, но это не в реализации, на которую я смотрю. Это было бы полезно только в довольно конкретной ситуации. –

0

Общий договор для методов equals (Object) и hashCode() утверждает, что объекты, которые являются равными, всегда будут возвращать хэш-коды, равные. Ergo, трудно понять, как сравнение хэш-кодов и равенство принесет вам что-либо с точки зрения производительности, особенно там, где строки являются объектом.

(Side Примечание: Убедитесь, что s1 и s2 не нуль, прежде чем назвать это, как написано.)

Смежные вопросы