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

Java 8: операция объединения строк имеет значительное влияние на производительность

Я просматривал недавно добавленные функции, представленные на Java-8. Одна простая функция, недавно добавленная в класс String, для меня тихая, а это метод String Join.

Пример:

String.join(" ", "AZY","BAX"); // returns AZY BAX

Для любопытства я проверил производительность (время выполнения) этой функции, написав простой Java-код

public static void main(String[] args) {
    long start = System.nanoTime();
    String abc= String.join(" ,"AZY","BAX" … // joining 1000 words of size 3 char;
    long diff = System.nanoTime() - start;
    System.out.println(" Java 8 String Join " + diff);

     start = System.nanoTime();
    abc= "AZY"+"BAX"+"CBA"+ … // adding 1000 word of size 3 char;
    diff = System.nanoTime() - start;
    System.out.println(" Tranditional " + diff);

    start = System.nanoTime();
    new StringBuilder().append("AZY").append("BAX").appe… // appending 1000 word of size 3 char;
    diff = System.nanoTime() - start;
    System.out.println(" String Builder Append " + diff);

}

Результат для меня не так увлекателен (время в neno sec)

Java 8 String Join     1340114
Tranditional             59785
String Builder Append   102807

Сложность - это o (n) - на самом деле это (n * Размер отдельной длины элемента)

Другие показатели производительности (память и т.д.) Я не измерил.

Мои вопросы:

  • Что-то не так в моих измерениях (большую часть времени я верю в парней jdk).
  • Какова цель добавления API-интерфейса объединения в класс String
  • Есть ли какой-либо анализ производительности для Java 8?
4b9b3361

Ответ 1

Прежде всего. Это не то, как вы используете microbench Java

Прочитайте Как мне сначала написать правильный микро-тест в Java?. Ваши номера абсолютно неактуальны, поэтому игнорируем их.

Глядя на второй пример:

abc= "AZY"+"BAX"+"CBA"+...

Они выглядят как константы времени компиляции для меня. Этот String был бы объединен во время компиляции, и было бы нечего сравнивать. Это бесполезное сравнение, поскольку вся точка StringBuilder или String.join заключается в объединении String, которые не являются постоянной времени компиляции.

Перемещение на сравнение StringBuilder и String.join. Посмотрев исходный код:

public static String join(CharSequence delimiter, CharSequence... elements) {
    Objects.requireNonNull(delimiter);
    Objects.requireNonNull(elements);
    // Number of elements not likely worth Arrays.stream overhead.
    StringJoiner joiner = new StringJoiner(delimiter);
    for (CharSequence cs: elements) {
        joiner.add(cs);
    }
    return joiner.toString();
}

В этом случае используется StringJoiner. A StringJoiner просто использует a StringBuilder под капотом, поэтому они эквивалентны.

Часто гораздо более информативно смотреть на код, чем на то, чтобы попробовать и сравнить производительность. Даже если вы правильно проводите тесты.

Также стоит отметить, что ваш первый метод с join объединяет 1000 String в "" (пробел). В то время как ваш метод StringBuilder просто присоединяет их вместе. Эти два не совпадают.

Точка метода String.join заключается в том, что вы можете сделать:

String.join(", ", "a", "b", "c") // result is "a, b, c"

С помощью StringBuilder вам нужно будет добавить намного больше кода.