gpt4 book ai didi

parsing - 并行计算/解析列表元素(链接)

转载 作者:行者123 更新时间:2023-12-02 18:34:19 25 4
gpt4 key购买 nike

无法理解并行计算列表元素的正确方法是什么,但在不计算元素时(并行)阻塞主线程。用例:我有一个 URL 链接列表和一个简单的 html 页面解析器,我如何通过并行解析每个页面来减少从给定页面获取信息所需的时间,然后返回一个包含一些 JSON 数据的简单列表.

据我了解,我有两个选择:

与 future 并行的方式

我有一个在 Future 中提取一些 JSON 数据的方法:

def extractData(link: String): Future[JValue] = // some implementation

我只是将其映射到链接列表上,其类型为 List[Future[JValue]]:

val res: List[Future[JValue]] = listOfLink.map(extractData)

如果我调用 sequence (例如从 Scalaz 或我自己的实现)遍历此列表并将其转换为 Future[List[JValue]],则链接仍然会按顺序处理,但是一个单独的线程,这不会给我任何效率,导致结果我需要获得一个 List[JValue]

尝试使用 ParSeq 进行计算

在此选项中,我有一个仅提取数据的函数:

def extractData(link: String): JValue = // some implementation

但这次在集合上调用.par:

val res: ParSeq[JValue] = listOfLinks.map(extractData)

但是这样我不太明白如何在不计算孔列表的情况下阻止主线程,而不按顺序解析每个链接

对于 Akka,我不能在这里使用 actor,所以只能使用 FuturePar*

最佳答案

当您将 extractData 映射到集合上时,链接将被并行处理。考虑一个稍微简化的例子:

import scala.concurrent._
import ExecutionContext.Implicits.global

def extractData(s: String) = future {
printf("Starting: %s\n", s)
val i = s.toInt
printf("Done: %s\n", s)
i
}

val xs = (0 to 5).map(_.toString).toList

val parsed = Future.sequence(xs map extractData)

现在您将看到类似以下内容的内容,这清楚地表明这些内容没有按顺序处理:

Starting: 0
Done: 0
Starting: 2
Done: 2
Starting: 1
Starting: 4
Done: 1
Starting: 3
Starting: 5
Done: 5
Done: 4
Done: 3

请注意,您可以使用 Future.traverse 来避免创建 futures 的中间列表:

val parsed = Future.traverse(xs)(extractData)

无论哪种情况,您都可以使用 Await 进行阻止:

val res = Await.result(parsed, duration.Duration.Inf)

作为脚注:我不知道您是否打算使用 Dispatch执行 HTTP 请求,但如果没有,则值得一看。它还提供了完美集成的 JSON 解析,并且文档中充满了如何使用 future 的有用示例。

关于parsing - 并行计算/解析列表元素(链接),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18238078/

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