concurrency - F#中的并行处理

标签 concurrency f#

我在玩 async在 F# 中。这看起来对吗,还是我在破坏东西?

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

最佳答案

首先,使用 async 有点反模式。用于并行 CPU 处理。有关更多信息,请参阅这些问题和答案:

Why shouldn't I use F# asynchronous workflows for parallelism?

Task Parallel Library vs Async Workflows

其次,您的 fib函数应该被重写为尾递归,这是来自 here 的一个例子(包括更改为 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)

关于concurrency - F#中的并行处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11181109/

相关文章:

java - 跨线程变量的每次读取都应该是 volatile 的、原子性的还是由同步包装的?

generics - 当应用于幻像类型时,此构造导致代码的通用性降低。

f# - 生成字符串时Expecto FsCheck获取堆栈溢出异常

Java8;在一个线程上利用 sleep 时间,但可调用多个线程

java - 没有 volatile 的双重检查锁定(但使用 VarHandle 释放/获取)

Java 对象分配开销

java - 如何在java中使用CAS(比较和交换)?

f# - 如何取消装箱 F# 元组对象,其中元组具有任意数量的元素

.net - Visual Studio 中的 F# 交互式热键

.net - ML.NET:如何解决 "Column with role MatrixColumnIndex should be a known cardinality U4 key, but is instead ' UInt3 2'"