首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当使用并行集合时,大量执行哪些操作?奇怪的行为

当使用并行集合时,大量执行哪些操作?奇怪的行为
EN

Stack Overflow用户
提问于 2011-09-18 14:02:36
回答 2查看 475关注 0票数 5

在Scala中输入以下小的顺序程序及其并行版本:

代码语言:javascript
复制
/* Activate time measurement in "App" class. Prints [total <X> ms] on exit. */
util.Properties.setProp("scala.time", "true")
/* Define sequential program version. */
object X extends App { for (x <- (1 to 10)) {Thread.sleep(1000);println(x)}}
/* Define parallel program version. Note '.par' selector on Range here. */
object Y extends App { for (y <- (1 to 10).par) {Thread.sleep(1000);println(y)}}

使用X.main(Array.empty)执行X会给出:

代码语言:javascript
复制
1
2
3
4
5
6
7
8
9
10
[total 10002ms]

而Y与Y.main(Array.empty)给出:

代码语言:javascript
复制
1
6
2
7
3
8
4
9
10
5
[total 5002ms]

到目前一切尚好。但是,程序的以下两个变体又如何呢?

代码语言:javascript
复制
object X extends App {(1 to 10).foreach{Thread.sleep(1000);println(_)}}
object Y extends App {(1 to 10).par.foreach{Thread.sleep(1000);println(_)}}

分别给我[total 1002ms][total 1002ms]的运行时。,这怎么可能?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-09-18 16:27:15

这与并行集合无关。这个问题隐藏在函数文字中。如果让编译器显示AST (带有选项-Xprint:typer),您可以看到它:

代码语言:javascript
复制
for (x <- (1 to 10)) {Thread.sleep(1000);println(x)}

产生

代码语言:javascript
复制
scala.this.Predef.intWrapper(1).to(10).foreach[Unit](((x: Int) => {
  java.this.lang.Thread.sleep(1000L);
  scala.this.Predef.println(x)
}))

鉴于

代码语言:javascript
复制
(1 to 10).foreach{Thread.sleep(1000);println(_)}

产生

代码语言:javascript
复制
scala.this.Predef.intWrapper(1).to(10).foreach[Unit]({
  java.this.lang.Thread.sleep(1000L);
  ((x$1: Int) => scala.this.Predef.println(x$1))
})

有一点不同。如果希望得到预期的结果,则必须将foreach-表达式更改为

代码语言:javascript
复制
(1 to 10).foreach{x => Thread.sleep(1000);println(x)}

但有什么不同呢?在您的代码中,您向foreach声明一个块,在执行该块之后,它将返回要执行的函数。然后将返回的函数传递给foreach,而不是包含它的块。

这个错误是经常犯的。它与下划线文字有关。也许this question能帮你。

票数 7
EN

Stack Overflow用户

发布于 2014-01-02 22:38:09

一种有趣的思考方法是,因为scala是按值调用(Call by name vs call by value in Scala, clarification needed),当您传递{Thread.sleep(1000);println()}以预先计算块{Thread.sleep(1000);println()}时,只需将生成的println(_)函数传递一次。当您执行foreach(x => Thread.sleep(1000);println(x))时,您将Thread.sleep(1000)和println(x)传递到函数foreach中。这只是另一种表达sschaef已经说过的话的方式。

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

https://stackoverflow.com/questions/7461942

复制
相关文章

相似问题

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