首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala中的并发处理

Scala中的并发处理
EN

Stack Overflow用户
提问于 2010-02-03 01:52:38
回答 2查看 961关注 0票数 4

我尝试在Scala中使用并发编程。在这个例子环境下,在StackOverflow环境下,编写了一个基于Euler项目问题1的程序。我尝试了三种方法:第一种是简单的执行,没有并行性。第二种是通过执行器和调用来使用java.util.concurrency API。第三,基于上面提到的页面,使用scala.Futures。我的目标是比较执行时间。

这是代码:

代码语言:javascript
复制
package sandbox

import java.util.concurrent._
import scala.actors._

object TestPool {

  def eval(n: Int): Boolean = (n % 3 == 0) || (n % 5 == 0)

  def runSingle(max: Int): Int = (1 until max).filter(eval(_)).foldLeft(0)(_ + _)

  def runPool(max: Int): Int = {

    def getCallable(i: Int): Callable[Boolean] = new Callable[Boolean] { def call = eval(i) }

    val pool = Executors.newFixedThreadPool(5)
    val result = (1 until max).filter(i => pool.submit(getCallable(i)).get).foldLeft(0)(_ + _)
    pool.shutdown
    pool.awaitTermination(Math.MAX_LONG, TimeUnit.SECONDS)

    result
  }

  def runFutures(max: Int): Int = (1 until max).filter(i => Futures.future(eval(i)).apply).foldLeft(0)(_ + _)

  /**
   * f is the function to be runned. it returns a Tuple2 containing the sum and the 
   * execution time.
   */
  def test(max: Int, f: Int => Int): (Int, Long) = {
    val t0 = System.currentTimeMillis
    val result = f(max)
    val deltaT = System.currentTimeMillis - t0

    (result, deltaT)
  }


  def main(args : Array[String]) : Unit = {
    val max = 10000

    println("Single : " + test(max, runSingle))
    println("Pool   : " + test(max, runPool))
    println("Futures: " + test(max, runFutures))
  }
}

以下是研究结果:

最大值= 10:

  • 单一:(23,31)
  • 人才库:(23,16)
  • 期货:(23,31)

最大值= 100:

  • 单一:(2318,33)
  • 总人数:(2318,31)
  • 期货:(2318,55)

最大值= 1000:

  • 单打:(233168,42)
  • 总人数:(233168,111)
  • 期货:(233168 364)

最大值= 10000:

  • 单打:(23331668,144)
  • 总人数:(23331668,544)
  • 期货:.。3分钟后我取消了执行

显然,我不能正确地使用来自Java和Scala的并发API。所以我问:我的错误在哪里?使用并发的更合适的形式是什么?关于斯卡拉演员?有可能使用它们吗?

EN

回答 2

Stack Overflow用户

发布于 2010-02-03 02:03:37

你期待什么结果?您是否期望这些方法中的一种会比其他方法执行得更好?您是否期望该程序针对不同的执行方法进行不同的扩展?

你的机器有几个核心?如果你只有一个核心,那么你应该期待的时间是线性增长的工作是要做的。在运行过程中,您的cpu使用情况如何?数字是可重复的吗?

您还没有考虑到JVM Hotspot热身时间的影响,这可能会给这样的微基准带来大量问题。

票数 1
EN

Stack Overflow用户

发布于 2010-02-03 11:37:56

我想您使用的是Scala2.7。基本上,filtermap on Range (1 until max的结果)是非严格的,这意味着它将按需计算,并且每次尝试访问它的结果时都会计算。

试试看,例如:

代码语言:javascript
复制
val y = (1 to 10).filter{x => println("Filtering "+x); x % 2 == 0}.map{x => println("Mapping "+x); x * 2}
println(y(0))
println(y(1))
println(y(2))
println(y(0))

结果,不管怎么说,你的平行的东西是连续运行的。在范围中添加一个.force,就可以了。

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

https://stackoverflow.com/questions/2189133

复制
相关文章

相似问题

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