【发布时间】:2017-05-26 15:05:29
【问题描述】:
有人可以向我解释为什么以下代码在流版本中比通过返回主列表的子列表比仅过滤器更快吗?
public static final int N = 50000000;
static List<Integer> sourceList = new ArrayList<>();
static {
for (int i = 0; i < N; i++) {
sourceList.add(i);
}
}
@Benchmark
public List<Pair<Integer, Integer>> vanilla() {
List<Pair<Integer, Integer>> collect1 =
sourceList.stream()
.map(integer -> Pair.of(integer, integer))
.collect(Collectors.toList());
return collect1.subList(1000, 100000);
}
@Benchmark
public List<Pair<Integer, Integer>> stream() {
return sourceList.stream()
.map(value -> Pair.of(value, value))
.filter(value -> value.getLeft() > 1000 && value.getLeft() < 100000)
.collect(Collectors.toList());
}
Benchmark Mode Cnt Score Error Units
Test.stream avgt 20 9.867 ± 0.218 ns/op
Test.vanilla avgt 20 183.304 ± 8.550 ns/op
我使用 JMH 运行测试,但我不理解结果。我认为通过添加将 Integer 值包装在 Pair 中的映射函数将强制流创建所有新对象以将它们传递给 filter 方法,然后提取 Pair 的左侧部分进行比较。这对我来说听起来比没有过滤的其他方法更密集,结果只是原始列表的子列表,因此没有遍历整个列表。
我错过了什么吗?
【问题讨论】:
标签: java-8 java-stream