Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.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
Scala cats效果:使用'ParseSequence'时无法看到执行时间的减少`_Scala_Parallel Processing_Cats Effect - Fatal编程技术网

Scala cats效果:使用'ParseSequence'时无法看到执行时间的减少`

Scala cats效果:使用'ParseSequence'时无法看到执行时间的减少`,scala,parallel-processing,cats-effect,Scala,Parallel Processing,Cats Effect,我是新来的猫效应库,我遇到了一个并行执行的问题。我有一个我认为会受益的应用程序,但当我在一个玩具构造上测试这个想法时,我似乎看不到执行时间上的差异。我觉得我一定是错过了一些对别人来说很明显的东西,所以我想我应该试试运气。在下面的代码中,我有两个跨数字序列求和的实现(addInSequence和addInParallel),都是在run()函数中执行的。当我运行程序时,我注意到它们的运行时间几乎相同。我错过了什么明显的东西吗 导入cats.Monoid 导入cats.effect.{ExitCod

我是新来的猫效应库,我遇到了一个并行执行的问题。我有一个我认为会受益的应用程序,但当我在一个玩具构造上测试这个想法时,我似乎看不到执行时间上的差异。我觉得我一定是错过了一些对别人来说很明显的东西,所以我想我应该试试运气。在下面的代码中,我有两个跨数字序列求和的实现(
addInSequence
addInParallel
),都是在
run()
函数中执行的。当我运行程序时,我注意到它们的运行时间几乎相同。我错过了什么明显的东西吗

导入cats.Monoid
导入cats.effect.{ExitCode,IO,IOApp}
进口猫_
导入scala.concurrent.duration.{FiniteDuration,TimeUnit}
案例类结果[A](值:A,二次选择:双精度)
目标结果{
def total[A](结果:Seq[Result[A]])(隐式mon:Monoid[A]):结果[A]={
val out:Result[A]=results.foldLeft(Result.empty[A]){
(输出:结果[A],下一个:结果[A])=>
val newValue:A=mon.combine(out.value,next.value)
val aggTime:Double=out.secondsElapsed+next.secondsElapsed
结果(newValue、aggTime)
}
出来
}
def empty[A](隐式mon:Monoid[A]):结果[A]=结果(mon.empty,0d)
隐式val intAddMon:Monoid[Int]=新的Monoid[Int]{
覆盖def empty:Int=0
覆盖def联合收割机(x:Int,y:Int):Int=x+y
}
}
对象并行映射扩展IOApp{
def slowAdd(nums:Seq[Int]):Int=nums.foldLeft(0){
(out:Int,next:Int)=>
val seconds:TimeUnit=java.util.concurrent.TimeUnit.seconds
val延迟:IO[单位]=IO.睡眠(有限持续时间(1L,秒))
delay.unsafeRunSync()
出+下一个
}
def timeIt[A](操作:=>A):结果[A]={
val start:Double=System.nanoTime/1e9
val out:A=op
val stop:Double=System.nanoTime/1e9
结果(输出、停止-启动)
}
def附加序列(第一个:序列[Int],第二个:序列[Int],第三个:序列[Int]):IO[结果[Int]={
val partialSums:Seq[Result[Int]=Seq(first,second,third).map(ns=>timeIt(slowAdd(ns)))
IO(结果总计(部分))
}
def addInParallel(第一个:Seq[Int],第二个:Seq[Int],第三个:Seq[Int]):IO[Result[Int]={
val ioSeq:List[IO[Result[Int]]]=List(第一、第二、第三).map(ns=>IO(timeIt(slowAdd(ns)))
val sums:IO[List[Result[Int]]]=ioSeq.parSequence
为了{
partialSums两件事:

  • 并行操作不能保证总是更快。如果顺序操作很短,则分派到多个线程以及稍后收集所有结果的开销可能大于加速

  • 看一看您正在测量的内容。您有一个顺序操作可以完成X工作量,或者有三个操作可以完成X/3工作量。您测量所有这些操作,然后比较:顺序运行X的时间与运行X/3的总时间在三个任务中的工作量。如果顺序运行大约需要3秒钟,则每次并行运行需要3秒钟根据这个逻辑,两个版本都需要3秒,这可能是对CPU使用时间的测量,但如果我们测量从开始工作到结束的时间,则不完全正确

  • 如果我运行你的代码,我会

    @ ParallelMap.main(Array[String]())
    List((Serial,Result(30,12.058612958004232)), (Parallel,Result(30,12.005087116995128)))
    
    但是,如果改为运行此代码:

    object ParallelMap extends IOApp {
    
      def slowAdd(nums: Seq[Int]): Int = nums.foldLeft(0) {
        (out: Int, next: Int) =>
          val seconds: TimeUnit = java.util.concurrent.TimeUnit.SECONDS
          val delay: IO[Unit] = IO.sleep(FiniteDuration(1L, seconds))
          delay.unsafeRunSync()
          out + next
      }
    
      def timeIO[A](op: IO[A]): IO[Result[A]] = for {
        start <- IO(System.nanoTime / 1e9)
        out <- op
        stop = System.nanoTime / 1e9
      } yield Result(out, stop - start)
    
    
      def addInSequence(first: Seq[Int], second: Seq[Int], third: Seq[Int]): IO[Result[Int]] = {
        timeIO(IO(List(first, second, third).map(ns => slowAdd(ns)).sum))
      }
    
      def addInParallel(first: Seq[Int], second: Seq[Int], third: Seq[Int]): IO[Result[Int]] = {
        // I changed is as little as possible so that you would still see
        // similarity to your code, but normally I would write
        // .parTraverse(f) instead of .map(f).parSequence
        timeIO(List(first, second, third).map(ns => IO(slowAdd(ns))).parSequence.map(_.sum))
      }
    
      def run(args: List[String]): IO[ExitCode] = {
        val nums: Seq[Int] = 1 to 4
        val results: IO[Seq[(String, Result[Int])]] = for {
          serial <- addInSequence(nums, nums, nums)
          parallel <- addInParallel(nums, nums, nums)
        } yield Seq(("Serial", serial), ("Parallel", parallel))
        val report: IO[Unit] = results.map(println)
        report.unsafeRunSync()
        IO(ExitCode.Success)
      }
    }
    

    这表明并行计算的速度是顺序计算的3倍。

    您将对所有单独任务的执行时间求和。显然,无论这些任务是顺序运行还是并行运行,您都会得到大致相同的结果。这是完全有道理的。我确信我构建了并行计算谢谢你的评论。
    @ ParallelMap.main(Array[String]())
    List((Serial,Result(30,12.006349742005114)), (Parallel,Result(30,4.003020468982868)))