有没有map
的替代品可以并行地对列表进行评估?我不需要它是惰性的。
类似于:pmap :: (a -> b) -> [a] -> [b]
让我执行pmap expensive_function big_list
,并让所有核心都达到100%。
有没有map
的替代品可以并行地对列表进行评估?我不需要它是惰性的。
类似于:pmap :: (a -> b) -> [a] -> [b]
让我执行pmap expensive_function big_list
,并让所有核心都达到100%。
是的,可以看一下parallel package:
ls `using` parList rdeepseq
将使用 rdeepseq
策略并行评估列表的每个元素。注意,如果您的元素太便宜以至于并行评估每个元素不会带来好处(因为这样可以节省为每个元素激发的开销),则使用适当的块值使用 parListChunk
可能会提供更好的性能。
编辑:根据您的问题,我觉得应该解释一下为什么这是一个答案。那是因为Haskell是惰性的!考虑这个声明
let bs = map expensiveFunction as
还没有进行任何计算。你只是创建了一个将 expensiveFunction
映射的惰性计算表达式(thunk)。那么我们如何并行地对其进行求值呢?
let bs = map expensiveFunction as
cs = bs `using` parList rdeepseq
现在不要再使用bs
列表进行未来的计算,改为使用cs
列表。也就是说,您不需要并行映射,而是可以使用常规(惰性)映射和并行评估策略。
编辑:如果您仔细查看,您会发现parMap函数可以将我展示的内容包装成一个帮助函数。
回应您的评论,下面的代码对您不起作用吗?对我有效。
import Control.Parallel.Strategies
func as =
let bs = map (+1) as
cs = bs `using` parList rdeepseq
in cs
parMap
函数。 parMap :: Strategy b -> (a -> b) -> [a] -> [b]
其中的策略参数是类似于rdeepseq
的东西。
而且还有parMap
在par-monad包中(您会从纯Haskell步入并行monad):
parMap :: NFData b => (a -> b) -> [a] -> Par [b]
par-monad 包的 文档在此处。
ghc -O2 -threaded blah.hs --make
)编译代码,并在运行时使用正确的 RTS 选项(./blah +RTS -Nx
,其中x
是你想要使用的核心数,例如2
)?需要注意的是,在 GHC 7 中,你只需输入ghc -O2 -threaded -with-rtsopts=-N blah.hs
,然后运行./blah
即可。 - Thomas M. DuBuisson