我希望将一个适度昂贵的函数映射到一个大的懒惰seq并行.pmap很棒,但我对上下文切换很不满意.我想我需要增加传递给每个线程的工作块的大小.
我写了一个函数来将seq分解为块并将函数pmap到每个块上并重新组合它们.这"有效",但结果并不壮观.原始代码基本上如下所示:
(pmap eval-polynomial (range x) coificients)
Run Code Online (Sandbox Code Playgroud)
我怎么能在保持懒惰的同时真正挤压它?
我正在尝试解析一个包含一百万行的文件,每一行都是一个json字符串,其中包含一些关于书籍的信息(作者,内容等).我正在使用iota加载文件,因为我的程序会抛出一个OutOfMemoryError如果我尝试使用slurp.我也用cheshire来解析字符串.该程序只需加载一个文件并计算所有书籍中的所有单词.
我的第一次尝试包括pmap做繁重的工作,我认为这基本上会利用我所有的cpu核心.
(ns multicore-parsing.core
(:require [cheshire.core :as json]
[iota :as io]
[clojure.string :as string]
[clojure.core.reducers :as r]))
(defn words-pmap
[filename]
(letfn [(parse-with-keywords [str]
(json/parse-string str true))
(words [book]
(string/split (:contents book) #"\s+"))]
(->>
(io/vec filename)
(pmap parse-with-keywords)
(pmap words)
(r/reduce #(apply conj %1 %2) #{})
(count))))
Run Code Online (Sandbox Code Playgroud)
虽然它似乎确实使用了所有核心,但每个核心很少使用超过50%的容量,我的猜测是它与pmap的批量大小有关,因此我偶然发现了相对较旧的问题,其中一些注释引用了该clojure.core.reducers库.
我决定使用reducers/map以下方法重写函数:
(defn words-reducers
[filename]
(letfn [(parse-with-keywords [str]
(json/parse-string str true))
(words [book]
(string/split (:contents book) #"\s+"))]
(->> …Run Code Online (Sandbox Code Playgroud)