Сравнение номеров быстрее, чем сравнение строк?

Я слышал, что хэширование (т.е. преобразование строки или объекта в число) используется для строк и т.д., потому что проще сравнивать числа, чем строки. Если это правда, в чем причина этого?

Ответ 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 (разные строки разной длины могут быть фактически равны, а разные символы в разных блоках кода сравниваются по-разному).


Хеширование обычно используется для преобразования строки в индекс массива.