Как Java 8 mapToInt (mapToInt (e → e)) улучшает производительность точно?

Я читаю книгу "Java 8 Lambdas", и в какой-то момент автор говорит: "Это хорошая идея использовать примитивные специализированные функции, где это возможно, из-за выгоды от производительности. ".

Он имеет в виду здесь mapToInt, mapToLong и т.д.

Дело в том, что я не знаю, откуда это происходит, если честно.

Рассмотрим пример:

    // Consider this a very very long list, with a lot of elements
    List<Integer> list = Arrays.asList(1, 2, 3, 4);

    //sum it, flavour 1
    int sum1 = list.stream().reduce(0, (acc, e) -> acc + e).intValue();

    //sum it, flavour 2
    int sum2 = list.stream().mapToInt(e -> e).sum();

    System.out.println(sum1 + " " + sum2);

Итак, в первом случае я использую сокращение для суммирования значений, поэтому функция BinaryOperator будет получать все время int (acc) и Integer (текущий элемент коллекции), а затем будет выполнять распаковку Целое число к int (acc + e) ​​

Во втором случае я использую mapToInt, который распаковывает каждый Integer в int и затем суммирует его.

Мой вопрос в том, есть ли преимущество второго подхода? Также, что точка карты int, когда я мог бы использовать карту?

Итак, да, все ли это просто синтаксис сахара или он имеет некоторые преимущества в производительности? В случае, если это так, пожалуйста, предложите некоторую информацию

Привет,

Ответ 1

В

есть дополнительный уровень бокса.
int sum1 = list.stream().reduce(0, (acc, e) -> acc + e).intValue();

поскольку функция сокращения является BinaryOperator<Integer> - она ​​получает два значения Integer, освобождает их, добавляет их, а затем повторно заполняет результат. Версия mapToInt распаковывает элементы Integer из списка один раз, а затем работает с примитивными значениями int с этой точки как IntStream.