There is no performance difference between .reduce(0, (x,y) -> x+y)
and .reduce(0, Integer::sum)
. The differences are handled at compile time:
For the lambda expression, a synthetic method will be generated holding the lambda’s body, x+y
. In contrast, Integer::sum
refers to an existing method, which has exactly the same code. From that point, all that happens, will be the same. Your class will request the JRE to generate an implementation of the functional interface whose function method will invoke the specified method, the synthetic method or the existing one, both doing the same.
So in either case, you will end up with a JRE generated BinaryOperator
which will invoke a method which returns the sum of both int
arguments. Since there is no technical difference, there can’t be any performance difference.
But as holi-java correctly pointed out, both variants incorporate unnecessary boxing overhead. A BinaryOperator<Integer>
receives two Integer
instances, which is fine if both are existing ones, stemming from the collection, but will also return an Integer
, which will be the boxed representation of the sum of the input. That sum might get passed into the next evaluation of the BinaryOperator<Integer>
, being unboxed again.
In contrast,
int sum = numbers.stream().mapToInt(Integer::intValue).sum();
only has to unbox the objects from the collection, but will never box or unbox intermediate sums again. Note that you need a fairly large number of elements, before using parallelStream()
instead of stream()
will pay off.