首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >并行计算/解析列表元素(链接)

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

Stack Overflow用户
提问于 2013-08-14 17:12:41
回答 1查看 180关注 0票数 3

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

据我所知,我有两个选择:

并发方式与期货

我有一种方法可以在将来提取一些JSON数据:

代码语言:javascript
运行
复制
def extractData(link: String): Future[JValue] = // some implementation

我只需将其映射到链接列表上,其中的类型是List[FutureJValue]:

代码语言:javascript
运行
复制
val res: List[Future[JValue]] = listOfLink.map(extractData)

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

尝试使用ParSeq进行计算

在这个选项中,我有一个函数,它只提取数据:

代码语言:javascript
运行
复制
def extractData(link: String): JValue = // some implementation

但是这次调用集合上的.par

代码语言:javascript
运行
复制
val res: ParSeq[JValue] = listOfLinks.map(extractData)

但在这种情况下,我不太明白如何阻塞主线程,而不按顺序解析每个链接,就无法计算孔列表。

至于阿克卡,我只是不能在这里使用演员,所以只有FuturePar*

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-14 17:39:41

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

代码语言:javascript
运行
复制
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)

现在,您将看到如下内容,它清楚地表明,这些事情不是按顺序处理的:

代码语言:javascript
运行
复制
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来避免创建期货的中间列表:

代码语言:javascript
运行
复制
val parsed = Future.traverse(xs)(extractData)

在这两种情况下,您都可以使用Await阻止

代码语言:javascript
运行
复制
val res = Await.result(parsed, duration.Duration.Inf)

作为脚注:我不知道您是否计划使用Dispatch来执行HTTP请求,但如果没有,则值得一看。它还提供了集成良好的JSON解析,文档中充满了如何使用未来的有用示例。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18238078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档