【发布时间】:2014-08-12 16:21:42
【问题描述】:
我正在阅读《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);
所以,在第一种情况下,我使用 reduce 对值求和,因此 BinaryOperator 函数将一直接收一个 int ( acc ) 和一个 Integer ( 集合的当前元素 ),然后对整数到 int (acc + e)
在第二种情况下,我使用 mapToInt,它将每个 Integer 拆箱成一个 int,然后对其求和。
我的问题是,第二种方法有什么优势吗? 另外,什么时候我可以使用 map,将 map 转换为 int 有什么意义?
是的,这只是糖语法还是有一些性能优势?如果有,请提供一些信息
问候,
【问题讨论】:
-
与原语一起使用是一个优势,集合 api 通常与相应的对象对应物一起使用,因此可以避免
-
是的,但对我来说,拆箱的数量是一样的。这就是为什么我看不出优势从何而来
-
如果你追求最后一点的性能,你应该更喜欢
mapToInt(Integer::intValue)而不是mapToInt(e -> e)。 -
@Holger 他们不是等价的吗?
e -> e正在执行一个隐式拆箱操作,无论如何它都委托给 Integer.intValue -
@Alexander 是的,它将编译为委派给
intValue()的代码,而Integer::intValue将评估为无需该委派而直接调用intValue()的函数。它们是等价的,由于保存了一个委托级别,因此性能差异很小(非常小)。
标签: java lambda java-8 java-stream