簡體   English   中英

F#中的並行處理

[英]Parallel processing in F#

我在F#中玩async 這看起來是正確的,還是我在破壞東西?

let time f = 
    let before = System.DateTime.Now
    f () |> ignore
    let after = System.DateTime.Now
    after - before;;

let rec fib = function 0 | 1 -> 1
                         | n -> fib (n - 1) + fib (n - 2);;

let source = [45; 40; 45; 40]

let synchronous = time <| fun () -> List.map fib source

let para = time <| fun () -> source
                             |> List.map (fun n -> async {ignore <| fib n}) 
                             |> Async.Parallel
                             |> Async.RunSynchronously

特別是,如何從async塊返回結果? 我必須使用可變狀態嗎?

更新:這是另一種方法:

#r "FSharp.PowerPack.Parallel.Seq.dll"
open Microsoft.FSharp.Collections

let pseq = time <| fun () -> source
                             |> PSeq.map fib
                             |> PSeq.toList

首先,對於並行CPU處理使用async是一種反模式。 有關更多信息,請參閱以下問題和答案:

為什么我不應該使用F#異步工作流來實現並行化?

任務並行庫與異步工作流

其次,你的fib功能應重新編寫成尾遞歸,這里是從一個例子這里 (包括更改為BigInt ):

let fib n =
    let rec loop acc1 acc2 = function
        | n when n = 0I -> acc1
        | n -> loop acc2 (acc1 + acc2) (n - 1I)
    loop 0I 1I n

最后,完整的代碼:

let source = [| 45I; 40I; 45I; 40I |]

let sync = time <| fun () -> Array.map fib source

let para = time <| fun () -> Array.Parallel.map fib source

請注意,在這兩種情況下都會返回一個結果Array ,您只需將其丟棄在時間函數中。 time函數如何返回時間和結果?

let time f = 
    let watch = new System.Diagnostics.Stopwatch()
    watch.Start()
    let res = f ()
    watch.Stop()
    (res, watch.ElapsedMilliseconds)

用法保持不變,但現在顯示結果:

printfn "Sync: %A in %ims" (fst sync) (snd sync)
printfn "Para: %A in %ims" (fst para) (snd para)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM