好吧,所以我正在做ProjectEuler問題#14,並且我在擺弄優化以擺脫f#。F#:告訴我什麼我錯過了關於使用Async.Parallel
下面的代碼:
let evenrule n = n/2L
let oddrule n = 3L * n + 1L
let applyRule n =
if n % 2L = 0L then evenrule n
else oddrule n
let runRules n =
let rec loop a final =
if a = 1L then final
else loop (applyRule a) (final + 1L)
n, loop (int64 n) 1L
let testlist = seq {for i in 3 .. 2 .. 1000000 do yield i }
let getAns sq = sq |> Seq.head
let seqfil (a,acc) (b,curr) = if acc = curr then (a,acc) else if acc < curr then (b,curr) else (a,acc)
let pmap f l =
seq { for a in l do yield async {return f a} }
|> Seq.map Async.RunSynchronously
let pmap2 f l =
seq { for a in l do yield async {return f a} }
|> Async.Parallel
|> Async.RunSynchronously
let procseq f l = l
|> f runRules
|> Seq.reduce seqfil
|> fst
let timer = System.Diagnostics.Stopwatch()
timer.Start()
let ans1 = testlist |> procseq Seq.map // 837799 00:00:08.6251990
printfn "%A\t%A" ans1 timer.Elapsed
timer.Reset()
timer.Start()
let ans2 = testlist |> procseq pmap
printfn "%A\t%A" ans2 timer.Elapsed // 837799 00:00:12.3010250
timer.Reset()
timer.Start()
let ans3 = testlist |> procseq pmap2
printfn "%A\t%A" ans3 timer.Elapsed // 837799 00:00:58.2413990
timer.Reset()
爲什麼會出現Async.Parallel代碼運行相比,直線上升的地圖很慢?我知道我不應該看到這麼大的影響,因爲我只是在雙核心的Mac上。
請注意,我不想幫助解決問題#14,我只是想知道我的並行代碼有什麼問題。
爲什麼它並行然後同步呢?你的管道似乎很奇怪。 – 2010-04-20 21:41:50
因爲我不知道如何獲取值? 我的印象是,Async.Parallel提供了一個設置爲並行處理的列表,然後Async.RunSynchronously運行Async.Parallel-ized序列並等待它完成(但它是並行處理的) – 2010-04-20 21:43:53