【发布时间】:2018-06-27 08:49:43
【问题描述】:
以下是我正在开发的应用程序的简化版本。具体来说,我有兴趣对process-list 的执行时间进行基准测试。在函数process-list 中,我将输入列表划分为等于我希望并行执行的线程数的分区。然后我通过调用future 将每个分区传递给一个线程。最后,在main 中,我调用process-list 并用time 包裹它。 Time 应该返回process-list 完成的处理经过的时间,但显然,它只返回创建未来线程所需的时间,而不是等待未来执行完成。如何取消对 process-list 中的期货的引用,以确保未来线程执行完成所经过的时间?
(ns listProcessing
(:require [clojure.string]
[clojure.pprint]
[input-random :as input]))
(def N-THREADS 4)
(def element_processing_retries (atom 0))
(def list-collection
"Each element is made into a ref"
(map ref input/myList))
(defn partition-list [threads list]
"partition list into required number of partitions which is equal
to the number of threads"
(let [partitions (partition-all
(Math/ceil (/ (count list) threads)) list)]
partitions))
(defn increase-element [element]
(ref-set element inc))
(defn process-list [list]
"Process `members of list` one by one."
(let [sub-lists (partition-list N-THREADS list)]
(doseq [sub-list sub-lists]
(let [futures '()
myFuture (future (dosync (swap! element_processing_retries inc)
(map increase-element sub-list)))]
(cons myFuture futures)
(map deref futures)))))
(defn main []
(let [f1 (future (time (process-list input/mylist)))]
@f1)
(main)
(shutdown-agents)
下面是一个简化的列表输入示例:注意这里的输入是简化的,列表处理也是为了简化问题。
(ns input-random)
(def myList (list 1 2 4 7 89 12 34 45 56))
【问题讨论】:
-
我已经简化了问题
-
应该注意的是,您的
dosync似乎无限期地被阻止。如果你在它后面加上print,它永远不会打印。我不经常使用sync来知道为什么会这样,但这肯定会导致问题。 -
好像是因为
(map increase-element element)。element是一个数字,所以我不确定你想在那里做什么。你不能map超过一个数字。这会默默地失败,因为你吃不饱的未来会吞下错误。 -
"element" 是一个列表。我可能应该重命名它。它代表分区列表中的每个分区
-
不,
elements是每个分区。element是每个分区中的每个数字。我认为您对let和doseq感到困惑。您可能已经查看代码太久了。
标签: clojure benchmarking future