2 回答
TA贡献1821条经验 获得超4个赞
一和二使用 ForkJoinPool,它专为并行处理一项任务而设计,而 ThreadPoolExecutor 用于并发处理独立任务。所以一和二应该更快。
TA贡献1833条经验 获得超4个赞
当您使用 时.filter(element -> f(element)).collect(Collectors.toList())
,它会将匹配的元素收集到 a 中List
,而.collect(Collectors.partitioningBy(element -> f(element)))
将所有元素收集到两个列表中的任何一个中,然后您删除其中一个并仅通过 检索匹配项列表.get(true)
。
很明显,第二个变体只能在最佳情况下与第一个变体相当,即如果所有元素无论如何都与谓词匹配,或者当 JVM 的优化器能够删除冗余工作时。在最坏的情况下,例如当没有元素匹配时,第二个变体收集所有元素的列表,然后才删除它,而第一个变体不会收集任何元素。
第三个变体没有可比性,因为您没有展示实际的实现,而只是一个草图。将假设的实现与实际进行比较是没有意义的。您描述的逻辑与并行流实现的逻辑相同。所以你只是在重新发明轮子。您可能会做一些比参考实现稍微好一点的事情,或者只是更好地针对您的特定任务量身定制,但是您忽略 Stream API 实现者在持续数年的开发过程中已经考虑过的事情的可能性要高得多。
所以我不会对你的第三个变体下任何赌注。如果我们增加您完成第三个变体的实现所需的时间,那么它永远不会比仅使用其他变体中的任何一个更有效。
所以第一个变体是最有效的变体,特别是因为它也是最简单、最易读、直接表达你的意图的。
添加回答
举报