Я слышал, что хэширование (т.е. преобразование строки или объекта в число) используется для строк и т.д., потому что проще сравнивать числа, чем строки. Если это правда, в чем причина этого?
Сравнение номеров быстрее, чем сравнение строк?
Ответ 1
Это не обязательно так, но, вероятно, в большинстве случаев.
Рассмотрим следующую ситуацию:
Я хочу сравнить строку "яблоки" и "апельсины" . Если я только хочу определить "яблоки" == "апельсины" , мне нужно сравнить только первый символ каждой строки: 'a'!= 'O' = > "apples"!= "Апельсины". Если я использую строку и затем выполняю сравнение, она значительно медленнее, поскольку я должен анализировать обе строки и передавать их в алгоритм хеширования, прежде чем сравнивать результирующие целые числа.
Если, однако, мне нужно сделать это сравнение много раз, и, возможно, я много сравниваю "апельсины" с "орангутанами", то если я один раз перечеркиваю все строки и много раз делаю сравнения целых чисел, это будет работать быстрее. Это принцип, на котором основана хэш-карта.
Обратите внимание, однако, что хеширование строки полезно для прямых сравнений сравнений, оно не может определить, являются ли слова лексиграфически больше или меньше друг друга, поэтому упорядочивание строк невозможно с помощью метода хэширования. (Вот почему HashMap в Java неупорядочен).
Ответ 2
Сравнение двух чисел - это величины быстрее, чем сравнение двух строк (представляющих одинаковые числа). Сравнение двух чисел просто требует сравнения отдельных битов и может быть выполнено очень быстро с использованием любого из AND, XOR, 2 дополнений и т.д.
Сравнение двух строк очень медленное и дорогое. Большинство алгоритмов требуют итерации по всей строке и сопоставления каждого символа.
Например, скажем, мы хотим сравнить 9 с 12 (false). Для численного сравнения предположим, что алгоритм сравнивает индивидуальный бит. 9 = 1001 12 = 1100
Здесь алгоритм наихудшего случая будет сравнивать 4 бита.
Теперь, если мы представляем строки "9" и "12" в виде строк, они будут храниться в памяти по 16 бит (Recall: Java использует UTF-16 для представления строк в памяти) и должны быть переданы в сравнение строк алгоритм. Фактически, фактическая функция сравнения строк Java ниже:
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;
}
Как вы можете видеть, для сравнения String намного больше.
Ответ 3
Сравнение примитивных чисел, безусловно, быстрее, чем сравнение строк, потому что только одна компьютерная команда при сравнении строк в Java является методом. Но хеширование в Java используется по другой причине, Object.hashCode() используется в хэш-таблицах для быстрого поиска в коллекциях.
Ответ 4
В общем, у большинства компьютеров есть одна команда для сравнения целых чисел, длин и т.д. и займет не более пары циклов обучения. Строки обычно сравниваются с помощью функции/метода функции (может быть нечетное исключение из этого правила).
в Java, например, строка в основном представлена как
/** The value is used for character storage. */
private final char value[];
/** The offset is the first index of the storage that is used. */
private final int offset;
/** The count is the number of characters in the String. */
private final int count;
И метод equals равен
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;
Метод equals использует как this == anObject, так и n == anotherString.count, по сути целые сравнивает, даже до того, как он начнет сравнивать символы. Это займет намного больше времени, чем одна команда, которую выполняет целочисленное сравнение.
Сравнение C проще/быстрее, чем эквивалент Java, но он будет содержать какой-то цикл и несколько инструкций для каждого прохождения через цикл.
Это займет больше времени, чем одна команда, которую требует Integer Compare
Ответ 5
Да, но это не имеет ничего общего с хешированием.
Сравнение чисел включает в себя простые аппаратные команды, которые сравнивают биты.
Сравнение строк включает (а) итерацию через обе строки до тех пор, пока вы не найдете разные символы (в отличие от чисел фиксированного размера) и (б) много магии Unicode (разные строки разной длины могут быть фактически равны, а разные символы в разных блоках кода сравниваются по-разному).
Хеширование обычно используется для преобразования строки в индекс массива.