Почему функционирование быстрее, чем обязательно для больших объемов данных, и медленнее, чем обязательно для небольших объемов данных? - PullRequest
1 голос
/ 12 апреля 2019

Я хотел сравнить производительность циклов с потоками.Для этого я написал 2 метода.Оба отфильтровывают имена, начинающиеся с 'A', и возвращают их в виде строки.Если я сделаю это с 50 000 случайно сгенерированных имен, императив будет быстрее.Но если я сделаю это с 500 000 случайно сгенерированных имен, функциональный путь будет быстрее.

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

public String imperativeArray() {

String result = "";
  for(String name : arraytestSet) {
    if(name.startsWith("A")) {
       if(result.isEmpty()) {
          result += name;
       } else {
          result += "," + name;
       }
    }
  }
   return result;
}

public String functionalArray() {
   return Arrays.stream(arraytestSet)
     .filter(e -> e.startsWith("A"))
     .collect(Collectors.joining(","));
}

1 Ответ

0 голосов
/ 12 апреля 2019

Не должно быть никакой разницы в производительности между императивом и функционалом.Функциональное программирование улучшит читабельность кода с помощью предопределенных функций.Внутренне они должны делать подобный тип обработки.Одним из основных преимуществ функционального стиля является то, что вы можете понять код одним взглядом.Параллельные потоки могут быть быстрее, чем ваш императивный код, но параллельный поток можно использовать, если вы уверены, что данные будут огромными и получат выгоду от параллельной обработки.В противном случае параллельный поток будет медленнее, чем обычный поток.Возвращаясь к вашему примеру кода, я чувствую, что с помощью Collectors.joining вы получаете выигрыш в производительности, чем проверка if-else, потому что вы используете операцию добавления строки, которая будет продолжать создавать новый строковый объект при каждом добавлении.Но collectors.joining внутренне использует StringBuilder, поэтому он будет работать с одним объектом при каждом добавлении.

...