评论由:jim.blomo做出
在任务受CPU限制时,启动比CPU核心更多的线程不是一个好主意。目前(1.4版本)pmap使用无界线程池,因此分块序列将创建比预期的更多线程。最微不足道的改变是使用固定大小的线程池(ForkJoinPool是一个例子)。pmap与core.reducers的区别在于它是惰性的。这意味着它使用了逐个提交的ThreadPool.submit模型,而不是递归的fork/join模型。权衡包括
即使在分块序列上也强制进行预览
- + 无需更改threadPool
- - 违背分块的意图,这可能是出于某个原因在使用的
切换到固定大小线程池
- + 减少分块序列上cpu限制函数的竞争
- - 增加io限制函数的总实现时间
使用ForkJoinPool作为固定线程池(代替newFixedThreadPool)
- + 自动和动态并行
- - 设置更复杂(选择Java 6 vs 7实现,与core.reducers共享池)
我认为使用传统的固定大小线程池是正确的选择。大多数情况下,pmap的所有结果都将被实现,因此我认为没有必要严格限制预览大小。这也是map所做的决定。由于我们没有使用ForkJoin的主要优势(递归工作队列),因此我认为在clojure.core中设置它不值得。
我将使用Agent/pooledExecutor作为固定大小的线程。
如果我有遗忘或理解错误的地方,请告诉我。