gpt4 book ai didi

f# - Fire and no-wait (without do!) vs Fire and wait (do!) 有巨大的性能差异吗?

转载 作者:行者123 更新时间:2023-12-02 14:28:47 46 4
gpt4 key购买 nike

以下代码运行大约需要 20 秒。然而,取消注释 do! 后只用了不到一秒的时间。为什么会有这么大的差异?

更新:使用ag.Add时需要9秒。我已经更新了代码。

open FSharpx.Control

let test () =
let ag = new BlockingQueueAgent<int option>(500)

let enqueue() = async {
for i = 1 to 500 do
//do! ag.AsyncAdd (Some i) // less than a second with do!
ag.AsyncAdd (Some i) // it takes about 20 seconds without do!
//ag.Add (Some i) // This one takes about 9 seconds
//printfn "=> %d" i
}

async {
do! [ for i = 1 to 100 do yield enqueue() ]
|> Async.Parallel |> Async.Ignore
for i = 1 to 5 do ag.Add None
} |> Async.Start

let rec dequeue() =
async {
let! m = ag.AsyncGet()
match m with
| Some v ->
//printfn "<= %d" v
return! dequeue()
| None ->
printfn "Done"
}

[ for i = 1 to 5 do yield dequeue() ]
|> Async.Parallel |> Async.Ignore |> Async.RunSynchronously
0

最佳答案

如果没有 do!,您就不会等待 AsyncAdd 的结果。这意味着每次调用 enqueue() 时,您都会尽快启动 500 个 AsyncAdd 操作。尽管如果队列已满,每个 AsyncAdd 调用都会阻塞,但如果您不等待 AsyncAdd 的结果,那么您的 enqueue() 代码不会被阻止,并且它将继续启动新的 AsyncAdd 操作。

由于您要并行启动 100 个 enqueue() 操作,因此可能会尝试多达 五万 AsyncAdd 操作同时运行,这意味着线程池正在处理 49,500 个阻塞线程。这对您的系统提出了很多要求。实际上,您不会同时并行启动 100 个 enqueue() 操作,但您将启动与逻辑 CPU 数量一样多的 enqueue() 操作。对于这个答案的其余部分,我将假设您有一个具有超线程的四核处理器(正如您的 F# Async.Parallel |> Async.RunSynchronously only uses one of the eight CPU core? 问题似乎暗示的那样),因此这是 8 个逻辑 CPU,因此您将启动 8 个 enqueue 副本() 在任何内容阻塞之前,这意味着您将有 4,000 个 AsyncAdd 线程运行,其中 3,500 个将被阻塞。

另一方面,当您使用 do! 时,如果 AsyncAdd 被阻止,您的 enqueue() 操作也会被阻止,直到队列中有一个空位。因此,一旦队列中有 500 个项目,线程池中将不再有 (8*500 - 500 = 3500) 个阻塞的 AsyncAdd 线程,而是将有 8 个阻塞的 AsyncAdd 线程。线程(一个用于在八个逻辑 CPU 上运行的八个 enqueue() 操作中的每一个)。八个阻塞线程而不是 3,500 个意味着线程池不会进行 3,500 次分配,使用更少的 RAM 和 CPU 时间来处理所有这些线程。

正如我在 my answer to your previous question 中所说,看来您确实需要对异步操作有更深入的了解。除了我在该答案中链接到的文章( this articlethis series )之外,我还建议阅读 https://medium.com/jettech/f-async-guide-eb3c8a2d180a ,这是一篇关于 F# 异步操作以及您可能遇到的一些“陷阱”的相当长且详细的指南。我强烈建议您阅读这些文章,然后回来再次查看您的问题。随着您从阅读这些文章中获得更深入的理解,您也许能够回答自己的问题!

关于f# - Fire and no-wait (without do!) vs Fire and wait (do!) 有巨大的性能差异吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57652524/

46 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com