gpt4 book ai didi

f# - Async.Parallel 还是 Array.Parallel.Map?

转载 作者:行者123 更新时间:2023-12-02 20:56:28 25 4
gpt4 key购买 nike

我正在尝试实现我从 Don Syme 的博客中读到的模式

( https://blogs.msdn.microsoft.com/dsyme/2010/01/09/async-and-parallel-design-patterns-in-f-parallelizing-cpu-and-io-computations/ )

这表明利用异步 I/O 有机会大幅提高性能。我目前正在尝试使用 Array.Parallel.Map 以一种方式“工作”一段代码,看看是否可以使用 Async.Parallel 以某种方式实现相同的结果,但我真的不明白 Async.Parallel,并且无法让任何东西发挥作用。

我有一段代码(下面进行了简化以说明这一点),它成功地检索了一个 cusip 的一组数据。 (例如价格系列)

let getStockData cusip = 
let D = DataProvider()
let arr = D.GetPriceSeries(cusip)
return arr

let data = Array.Parallel.map (fun x -> getStockData x) stockCusips

因此,这种方法通过互联网与我的每只股票(可能多达 3000 只)的数据供应商建立连接,构建了一个数组数组,并返回一个数组数组(每只股票 1 个,带有价格)每一个系列)。诚然,我不明白 Array.Parallel.map 下发生了什么,但我想知道这是否是一个在幕后浪费资源的场景,并且使用异步 I/O 实际上可能会更快?因此,为了测试这一点,我尝试使用异步来创建此函数,并且我认为下面的函数遵循 Don Syme 的文章中使用 URL 的模式,但它不会使用“let!”进行编译。

let getStockDataAsync cusip = 
async { let D = DataProvider()
let! arr = D.GetData(cusip)
return arr
}

我得到的错误是:该表达式原本应具有 Async<'a> 类型,但这里具有 obj

类型

使用“let”而不是“let!”可以很好地编译,但我认为重点是您需要感叹号才能运行命令而不阻塞线程。

所以第一个问题实际上是,我上面的 getStockDataAsync 语法有什么问题,然后在更高的级别上,任何人都可以提供一些关于异步 I/O 的额外见解以及我提出的场景是否会从中受益,使其可能比 Array.Parallel.map 快得多吗?非常感谢。

最佳答案

F# 异步工作流程允许您实现异步计算,但是,F# 区分了普通计算和异步计算。这种差异由类型系统跟踪。例如,下载网页并同步的方法的类型为 string -> string (获取 URL 并返回 HTML),但是异步执行相同操作的方法的类型为 string -> Async<string> 。在 async block ,您可以使用 let!调用异步操作,但必须使用 let 调用所有其他(标准同步)方法。现在,您的示例的问题是 GetData操作是普通的同步方法,因此不能使用 let! 调用它。

在典型的 F# 场景中,如果您想将 GetData成员异步,您需要使用异步工作流程来实现它,因此您还需要将其包装在 async 中堵塞。在某些时候,您将到达确实需要异步运行某些原始操作的位置(例如,从网站下载数据)。 F# 提供了几种原始异步操作,您可以从 async 调用它们。阻止使用 let!AsyncGetResponse (这是 GetResponse 方法的异步版本)。所以,在你的 GetData方法,例如,您将编写如下内容:

let GetData (url:string) = async {
let req = WebRequest.Create(url)
let! rsp = req.AsyncGetResponse()
use stream = rsp.GetResponseStream()
use reader = new System.IO.StreamReader(stream)
let html = reader.AsyncReadToEnd()
return CalculateResult(html) }

总结是,您需要识别一些原始异步操作(例如等待 Web 服务器或文件系统),在此时使用原始异步操作并将使用这些操作的所有代码包装在 async 中。 block 。如果没有可以异步运行的原始操作,那么您的代码受 CPU 限制,您可以只使用 Parallel.map .

我希望这可以帮助您了解 F# 异步工作流程的工作原理。有关更多信息,您可以查看 Don Syme's blog post ,系列关于asynchronous programming by Robert Pickering ,或者我的F# web cast .

关于f# - Async.Parallel 还是 Array.Parallel.Map?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2477931/

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