评论人:jim.blomo
当工作受CPU限制时,不应创建比CPU核心更多的线程。当前(1.4)版本中,pmap使用无界的线程池,因此分块序列将创建比预期更多的线程。最不具侵入性的改变是使用固定大小的线程池(ForkJoinPool是一个例子)。pmap与core.reducers的不同之处在于它是惰性的,这意味着采用单个线程池.submit的模式,而不是递归的fork/join模式。权衡包括
即使对于分块序列也强制进行前瞻
- + 没有threadPool的更改
- - 与分块(可能被用于某个原因)作对抗
切换到固定大小的线程池
- + 减少了分块序列上CPU受限函数的竞争
- - 增加了I/O受限函数的总实现时间
使用ForkJoinPool作为固定大小的线程池(而不是newFixedThreadPool)
- + 自动和动态并行性
- - 更复杂的配置(选择Java 6与7的实现,将线程池与core.reducers共享)
我认为使用传统固定大小的线程池是正确的选择。大部分时间pmap的所有结果都将被实现,所以我认为没有必要严格关注前瞻的大小。这也是map所做的决定。由于我们未使用ForkJoin的主要优势(递归工作排队),我认为没有必要在clojure.core中设置它。
我将使用Agent/pooledExecutor作为固定大小的线程。
请告知我如果有什么遗忘或误解。