Haskell 中的并行映射

发布于 2024-10-31 11:54:40 字数 181 浏览 0 评论 0原文

是否有一些可以并行评估列表的 map 替代品?我不需要它来偷懒。

类似于: pmap :: (a -> b) -> [一]-> [b] 让我 pmap costly_function big_list 并使我的所有核心都处于 100%。

Is there some substitute of map which evaluates the list in parallel? I don't need it to be lazy.

Something like: pmap :: (a -> b) -> [a] -> [b] letting me pmap expensive_function big_list and have all my cores at 100%.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猫七 2024-11-07 11:54:40

参阅并行包

ls `using` parList rdeepseq

是的,请 通过 rdeepseq 策略并行评估列表中的每个元素。请注意,如果您的元素太便宜而无法获得并行评估每个元素的好处(因为它节省了每个元素的火花),则使用具有良好块值的 parListChunk 可能会带来更好的性能。

编辑:根据你的问题,我觉得我应该解释为什么这是一个答案。这是因为 Haskell 很懒! 这一说法

let bs = map expensiveFunction as

考虑一下“没有任何内容已被评估” 。您刚刚创建了一个映射 expenseFunction 的 thunk。那么我们如何并行评估它呢?

let bs = map expensiveFunction as
    cs = bs `using` parList rdeepseq

现在,在以后的计算中不要使用 bs 列表,而是使用 cs 列表。 IOW,您不需要并行映射,您可以使用常规(惰性)映射和并行评估策略。

编辑:如果你环顾四周,你会看到 parMap 函数执行我在此展示的操作,但包装在一个辅助函数中。

针对您的评论,以下代码不适合您吗?它对我有用。

import Control.Parallel.Strategies

func as =
        let bs = map (+1) as
            cs = bs `using` parList rdeepseq
        in cs

Yes, see the parallel package:

ls `using` parList rdeepseq

will evaluate each element of the list in parallel via the rdeepseq strategy. Note the use of parListChunk with a good chunk value might give better performance if your elements are too cheap to get a benefit evaluating each one in parallel (because it saves on sparking for each element).

EDIT: Based on your question I feel I should explain why this is an answer. It's because Haskell is lazy! Consider the statement

let bs = map expensiveFunction as

Nothing has been evaluated. You've just created a thunk that maps expensiveFunction. So how do we evaluate it in parallel?

let bs = map expensiveFunction as
    cs = bs `using` parList rdeepseq

Now don't use the bs list in your future computations, instead use the cs list. IOW, you don't need a parallel map, you can use the regular (lazy) maps and a parallel evaulation strategy.

EDIT: And if you look around enough you'll see the parMap function that does what I showed here but wrapped into one helper function.

In response to your comment, does the below code not work for you? it works for me.

import Control.Parallel.Strategies

func as =
        let bs = map (+1) as
            cs = bs `using` parList rdeepseq
        in cs
陈甜 2024-11-07 11:54:40

除了像 Tom 所描述的那样,您自己使用显式策略之外,parallel也导出parMap

 parMap :: Strategy b -> (a -> b) -> [a] -> [b]

其中策略参数类似于rdeepseq

par-monad 包中还有 parMap (你走出了纯 Haskell,进入了并行 monad):

 parMap :: NFData b => (a -> b) -> [a] -> Par [b]

par-monad 包是 记录在此处

Besides using explicit strategies yourself as Tom has described, the parallel package also exports parMap:

 parMap :: Strategy b -> (a -> b) -> [a] -> [b]

where the strategy argument is something like rdeepseq.

And there's also parMap in the par-monad package (you step out of pure Haskell, and into a parallel monad):

 parMap :: NFData b => (a -> b) -> [a] -> Par [b]

The par-monad package is documented here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文