Java 8 - Разница между уменьшением (0, Integer::sum) и уменьшением (0, (a, b) -> a+b)

Я новичок в Java 8 и нашел несколько способов сделать addition, multiply а также subtraction, Я буду публиковать вопрос только для добавления.

Я написал код ниже и собираю вывод в Sum1 и Sum2. Оба метода reduce(0, Integer::sum) а также .reduce(0, (a, b) -> a+b); дает тот же результат. Каков наилучший метод для повышения производительности, если используются большие целочисленные значения и почему?

List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);

Integer sum1 = numbers.stream().reduce(0, (a, b) -> a+b);
System.out.println("SUM ="+sum1);

Integer product = numbers.stream().reduce(0, (a, b) -> a*b);
System.out.println("PRODUCT = "+product);

int sum2 = numbers.stream().reduce(0, Integer::sum);
System.out.println("SUM 2= "+sum2);

Optional<Integer> sum3 = numbers.stream().reduce((a, b) -> (a + b));
System.out.println("SUM3="+sum3);

// Updated as per  @Hadi J comment
int sum4 = numbers.stream().mapToInt(Integer::intValue).sum();
System.out.println("Sum ="+sum4);

2 ответа

Какой метод лучше всего использовать с точки зрения производительности и при использовании больших целочисленных значений и почему?

Основная идея состоит в том, чтобы игнорировать автоматическую упаковку / распаковку при манипулировании примитивами и их объектными представлениями.

Добавление двух Integer объекты намного сложнее, чем добавление двух intпримитивы. Вы можете найти более подробную информацию в этом посте.

Так что лучший случай - это примитивный массив int[] и суммируем его элементы в аккумулятор типа int. Таким образом, здесь нет бокса.

Худший (но не худший) случай - это суммирование объекта Integer с примитивным int. Это вызовет распаковку первого аргумента. Вот как это работает, когда ваш исходный массив или коллекция содержит объекты (например, Integer[], List и т. Д....), а аккумулятор является примитивным. Это вызовет распаковку каждого элемента вашей коллекции ровно один раз, в то время как аккумулятор останется прежним.

Наихудший случай - суммирование коллекции объектов в Integer аккумулятор.

  1. Обычная старая Java:

    • Подведение итогов Integer[] в Integer

      Integer[] array = {0,1,2,3,4,5,6,7,8,9};
      Integer sum = 0;
      // Each element of the array will be unboxed exactly once
      // sum will be unboxed 10 times
      // result of the sum will be boxed 10 times
      for(int i : array) sum += i;
      
    • Подведение итогов Integer[] в int

      Integer[] array = {0,1,2,3,4,5,6,7,8,9};
      int sum = 0;
      // Each element of the array will be unboxed exactly once
      // result of the sum will be boxed 10 times
      for(int i : array) sum += i;
      
    • Подведение итогов int[] в int

      int[] array = {0,1,2,3,4,5,6,7,8,9};
      int sum = 0;
      // No boxing/unboxing at all
      for(int i : array) sum += i;
      
  2. Stream API

    • Уменьшение суммы Stream<Integer>

      Stream<Integer> stream = Stream.of(0,1,2,3,4,5,6,7,8,9);
      // Each element will be unboxed exactly once
      // The accumulator will be unboxed 10 times
      // The result of the sum operation will be boxed 10 times
      Integer sum = stream.reduce(0, Integer::sum);
      
    • Уменьшение суммы Stream<Integer> отображение на примитив int

      Stream<Integer> stream = Stream.of(0,1,2,3,4,5,6,7,8,9);
      // Each element will be unboxed exactly once
      // Neither accumulator not result will be unboxed/boxed
      int sum = stream.mapToInt(Integer::intValue).reduce(0, Integer::sum);
      
    • Уменьшение суммы IntStream

      IntStream stream = IntStream.of(0,1,2,3,4,5,6,7,8,9);
      // No boxing/unboxing at all
      int sum = stream.reduce(0, Integer::sum);
      // same as
      int sum2 = stream.sum();
      

Кое-что интересное: в Intellij IDEA, когда вы проводите мышью над функцией sum(), появляется всплывающая подсказка, подобная этой:

Возвращает сумму элементов в этом потоке. Это частный случай редукции и эквивалентен:

      Public abstract int sum() 
//equal function to
return reduce(0, Integer::sum);
Другие вопросы по тегам