由 jim.blomo 发布的评论
在任务是 CPU 密集型时,启动比 CPU 内核更多的线程并不是一个好主意。目前(1.4版本)pmap 使用无界线程池,因此分块序列将创建比预期更多的线程。最不具侵略性的更改是使用固定大小的线程池(ForkJoinPool 是一个例子)。pmap 与 core.reducers 不同的地方在于它懒惰。这意味着是采取了一次一个 ThreadPool.submit 模型,而不是递归的 fork/join 模型。权衡包括
即使对于分块序列,也要强制预览
没有改造线程池
减少了对分块的困难,而分块可能因某个原因而被使用
转向固定大小的线程池
减少分块序列上 CPU 密集型函数的竞争
增加 I/O 密集型函数的总实现时间
使用 ForkJoinPool 作为固定线程池(而不是 newFixedThreadPool)
自动和动态并行化
更复杂的设置(选择 Java 6 与 7 实现,与 core.reducers 共享池)
我认为使用传统的固定大小线程池是正确的选择。在大多数情况下,pmap 的所有结果都将实现,因此我认为节省注意力去严格限制预览大小是不值得的。这也是 map 所做的决定。由于我们没有使用 ForkJoin 的主要优势(递归工作队列),因此我认为在 clojure.core 中设置它不值得。
我将使用 Agent/pooledExecutor 作为固定大小线程。
如果我发现遗漏或误解了什么的话,请通知我。