我有两个昂贵的功能,它们是独立的。我想并行运行它们。我不想处理 future 之类的东西(我是Clojure的新手,很容易困惑)。

我正在寻找一种同时运行两个函数的简单方法。我希望它像以下一样工作

(defn fn1 [input] ...) ; costly
(defn fn2 [input] ...) ; costly

(let [[out1 out2] (conc (fn1 x) (fn2 y))] ...)

我希望它返回一个带有一对输出的向量。只有两个线程都终止后,它才应返回。理想情况下,conc应该适用于任何数量的输入。我怀疑这是一个简单的模式。

最佳答案

正如其他答案所示,您确实需要一个宏来保留所需的语法,尽管还有其他方法可以获取相同的行为。这是一种实现方法:

(defn f1 [x] (Thread/sleep 500) 5)
(defn f2 [y] 2)

(defmacro conc [& exprs]
  `(map deref
        [~@(for [x# exprs] `(future ~x#))]))

(time (let [[a b] (conc (f1 6) (f2 7))]
       [a b]))
; "Elapsed time: 500.951 msecs"
;= (5 2)

扩展显示了它是如何工作的:
(macroexpand-1 '(conc (f1 6) (f2 7)))
;= (clojure.core/map clojure.core/deref [(clojure.core/future (f1 6))
;=                                       (clojure.core/future (f2 7))])

您指定了两个函数,但是它可以与任意数量的表达式一起使用。

10-08 02:57