繁体   English   中英

用Clojure期货计算多头总和

[英]Computing a long sum with Clojure futures

运行此代码:

(ns playfield.core)

(defn sum
  [start end]
  (reduce + (range start end)))

(def size 1e8)

(defn -main
  [& args]
  (println (time (sum 0 size)))
  (println (time (let [left (future (sum 0 (/ size 2)))
                       right (future (sum (/ size 2) size))]
                   (+ @left @right)))))

给我这个输出:

"Elapsed time: 2742.185 msecs"
4999999950000000
"Elapsed time: 2605.541 msecs"
4.99999995E15

我原本希望第二个计算花费大约一半的时间,因为我将计算分布在两个线程上。 我究竟做错了什么?

我(加修饰你的榜样位(shutdown-agents)在结束-main )跑( lein run -m playfield.core )这两台机器上:

视网膜Macbook Pro,2012年中

  • 2.3 GHz英特尔酷睿i7
  • 16 GB RAM
  • Java(TM)SE运行时环境(内部版本1.7.0_45-b18)

结果:

serial:   2678.034 msecs
parallel: 1943.153 msecs
Parallel takes 72.3% of baseline.

请注意,这些结果与我最初的评论有所不同。 该数据是从REPL运行的。

联想Thinkstation S20

  • 3.07GHz英特尔至强W3550
  • 8 GB RAM
  • Java(TM)SE运行时环境(内部版本1.7.0_45-b18)

结果:

Serial:   12390.296313 msecs
Parallel:  6856.656525 msecs
Parallel takes 55.3% of baseline.

我可以想到基准测试时可能遇到的两个问题:

  1. 机器没有多个内核/ Java仅限于一个内核/否则将加载内核。
  2. 对JVM进行基准测试比较棘手。 通常,建议使用标准代替。 但是,我上面的数字只是使用time生成的,因此我不确定这里是否起作用。

编辑

我有一些更多的想法:

如@lgrapenthin所述,JVM选项会影响时间。 例如,lein使用以下两个选项来缩短启动时间-XX:+TieredCompilation -XX:TieredStopAtLevel=1 对于这种情况,更改此设置具有明显的区别:

$ LEIN_JVM_OPTS="" lein run -m 'speed.core'
Serial:   2496.435288 msecs
Parallel: 2045.084565 msecs
Parallel takes 81.9% of baseline. 

@Giuseppe的评论指出,正在积极使用4个内核(我认为这意味着充分利用)。 也许JVM具有很高的内存压力,并且CPU使用率正在使垃圾回收器疯狂地工作以使一些内存可用。 但是,我无法在本地复制此内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM