Подтвердить что ты не робот

Какой самый быстрый способ сравнить строки в Java?

Что самое быстрое сравнение двух строк в Java?

Есть ли что-то быстрее, чем равное?

EDIT: Я не могу помочь, чтобы прояснить проблему.

У меня есть две строки, которые сортируются в алфавитном порядке и ТОЧНО одинакового размера

Пример: abbcee и abcdee

Строки могут быть длинными до 30 символов

4b9b3361

Ответ 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.