一般来说,这两段代码之间是否存在性能差异?
List<Integer> list1 = someStream1.sorted().collect(toList());
// vs.
List<Integer> list2 = someStream2.collect(toList());
list2.sort(Comparator.naturalOrder())变量2显然是令人讨厌的,应该避免,但我很好奇,在流的主流(heh,主流)实现中是否有任何性能优化会导致这两者之间的性能差异。
我想,因为溪流拥有更多关于情况的信息,所以它将有更好的机会进行优化。我想,如果这上面加了一个findFirst()调用,它就会避开这类调用,而有利于min操作。
发布于 2018-09-21 18:15:41
这两种选择都应产生相同的最终结果。但运行时特性可能与不同。如果初始流是并行流,怎么办?然后,选项1将并行地进行排序,而选项2则不会进行“顺序”排序。结果应该是相同的,但总体运行时重新定位。CPU负载可能会有很大不同。
我肯定更喜欢选项1而不是2:为什么先创建一个列表,然后再排序呢?!
例如,设想您以后想要收集到一个不变的列表中。然后,所有遵循第二种模式的代码都会中断。然而,使用模式1编写的代码根本不会受到影响!
当然,在这里的例子中,这不应该导致问题,但是如果排序()发生在稍微不同的地方呢?!
发布于 2018-09-21 18:10:35
从概念上讲,流通常被视为正在处理/操作的“瞬态”数据,而收集流传递了您已经完成操作的概念。
虽然第二个片段应该起作用,但第一个片段将是更惯用的做事方式。
发布于 2018-09-21 18:25:23
在第一种情况下,排序发生在对collect的调用中。如果已经对流进行了排序,这将是一个非操作(数据将按原样传递)。可能不会有太大的区别,但是对已经排序的集合调用Collections.sort仍然是O(n)。
第一种情况还得益于并行执行,因为至少OpenJDK使用Arrays.parallelSort。
除此之外,第一行更简洁,更好地理解,并且在重构时更容易出错。
https://stackoverflow.com/questions/52448983
复制相似问题