user=> (.. Runtime getRuntime availableProcessors)
2
Run Code Online (Sandbox Code Playgroud)
并评估此示例:http://clojuredocs.org/clojure_core/clojure.core/pmap#example_684我得到
user=> (time (doall (map long-running-job (range 4))))
"Elapsed time: 12000.621 msecs"
(10 11 12 13)
user=> (time (doall (pmap long-running-job (range 5))))
"Elapsed time: 3000.454 msecs"
(10 11 12 13 14)
user=> (time (doall (pmap long-running-job (range 32))))
"Elapsed time: 3014.969 msecs"
(10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 3839 40 41)
user=> (time (doall (pmap long-running-job (range 33))))
"Elapsed time: 6001.526 msecs"
(10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42)
Run Code Online (Sandbox Code Playgroud)
我想知道为什么我必须通过33等待33秒.为了结果.pmap创建2(可用处理器)+ 2个线程,是吗?我认为当通过(范围5)时,它将在6秒内执行.为什么会有所不同?
实际上pmap并不遵守"处理器+2"的限制.这是常规map和future宏观工作方式的结果:
future 使用没有大小限制的缓存线程池;
map 产生一个分块序列,即一次总是强制32个元素的序列,即使一个块的开头只有一小部分被调用者实际消耗了.
最终结果是期货以pmap32块为单位并行发布.
请注意,这不违反了pmapdocstring中指定的合同.另一方面,代码可能导致人们相信"处理器+2"限制的意图是被尊重的 - 正如它map天真地写的那样.事实上,很pmap可能早于向chunked seqs移动,虽然我不太确定,但已经有一段时间了.