Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance Scala中的并发处理_Performance_Scala_Concurrency - Fatal编程技术网

Performance Scala中的并发处理

Performance Scala中的并发处理,performance,scala,concurrency,Performance,Scala,Concurrency,我正在尝试在Scala中使用并发编程。总部设在这里 StackOverflow,我在Euler项目的基础上编制了一个程序。 我尝试了三种方法:第一种是简单的执行,没有并行性。这个 第二个通过执行器和可调用项使用java.util.concurrency API。第三,基于上面提到的页面,使用scala.Futures。我的目标是比较执行时间 代码如下: package sandbox import java.util.concurrent._ import scala.actors._ ob

我正在尝试在Scala中使用并发编程。总部设在这里 StackOverflow,我在Euler项目的基础上编制了一个程序。 我尝试了三种方法:第一种是简单的执行,没有并行性。这个 第二个通过执行器和可调用项使用java.util.concurrency API。第三,基于上面提到的页面,使用scala.Futures。我的目标是比较执行时间

代码如下:

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)
  • 游泳池:(233168111)
  • 期货:(233168364)
最大值=10000:

  • 单人:(23331668144)
  • 游泳池:(23331668544)
  • 期货:。。。我在3分钟后取消了执行
显然,我无法正确使用Java和Scala中的并发API。所以我问: 我的错在哪里?使用并发的更合适形式是什么?
那Scala演员呢?有可能使用它们吗?

您希望得到什么结果?您是否期望其中一种方法的性能优于其他方法?您是否希望程序针对不同的执行方法进行不同的扩展

你的机器有多少芯?如果你只有一个核心,那么你应该期望时间随着要做的工作线性增加。在运行过程中,您的cpu使用情况如何?这些数字可以重复吗


您还没有考虑到JVM热点预热时间的影响,这可能会给这样的微基准测试带来实质性的问题

我假设您使用的是Scala 2.7。基本上,
Range
上的
filter
map
(直到max为止的
1的结果)是非严格的,这意味着它将按需计算,并且每次尝试访问它的结果时都会进行计算

试试这个,例如:

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
,就可以了