【发布时间】:2013-04-19 19:39:56
【问题描述】:
如何在 F# 中实现并行过滤?基本上我想做Array.Parallel.Choose,除了使用序列表达式来创建一个数组。
我试过了:
Async.Parallel [for x in 1..40 do yield async { if x % 5 = 0 then return x }]
但这是类型不匹配,因为 if 并不总是有值(即 Async<unit> 不是 Async<'a>)。
我正在迭代大量数字 (1,000,000,000 +),所以我不想预先生成序列。
if语句中的实际检查是:
let isPalindrome (x : int) = let numberArray = x.ToString().ToCharArray()
numberArray = Array.rev numberArray
尝试使用 PSeq:
[for x in 990000..999999 do for y in 990000..999999 do yield (x, y, x*y)]
|> PSeq.filter(fun (x, y, z) -> isPalindrome z)
|> Seq.max
这会产生OutOfMemoryException。
丑陋的解决方法:
let numberArray = [|990000..999999|]
let result = numberArray |> Array.Parallel.collect(fun x -> [| for y in numberArray do if isPalindrome (x*y) then yield (x, y, x*y)|])
|> Array.maxBy(fun (x, y, z) -> z)
【问题讨论】:
-
F# PowerPack 中有一个
PSeq(Parallel Sequence) 模块,你试过了吗?另外,如果您只是在过滤器中执行简单的mod,我怀疑您是否会通过使用并行序列来实现很多(如果有的话)性能改进...... -
@ildjarn
mod只是一个占位符。我实际上是在玩我对 Project Euler 问题 4 projecteuler.net/problem=4 的解决方案,看看我能把它扩大到多少。我希望避免使用外部库。 -
@ildjarn 我查看了
PSeq,但它似乎不能满足我的需求:即它适用于现有序列而不是序列生成 -
你明白序列是惰性的,对吧?有一个
seq生成器,并使用PSeq进行过滤。
标签: f# parallel-processing task-parallel-library plinq