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 - Fatal编程技术网

Performance Scala性能调优问题

Performance Scala性能调优问题,performance,scala,Performance,Scala,我是Scala新手,刚刚编写了以下程序: def isPrime(num: Int, primes: scala.collection.mutable.MutableList[Int]): Boolean = { primes.takeWhile( i => i * i <= num).forall( num % _ > 0) } //def isPrime(num: Int, primes: scala.collection.mutable.MutableList[In

我是Scala新手,刚刚编写了以下程序:

def isPrime(num: Int, primes: scala.collection.mutable.MutableList[Int]): Boolean = {
  primes.takeWhile( i =>  i * i <= num).forall( num % _ > 0)
}
//def isPrime(num: Int, primes: scala.collection.mutable.MutableList[Int]): Boolean = {
//  !primes.forall(num%_!=0)
//}


def primeListUnder(upper: Int) = { 
  val primes=scala.collection.mutable.MutableList(2,3); 
  var num=4
  while(num<upper) {
    if(isPrime(num,primes))
    { 
      primes+=num
    }
    num+=1
  }
  primes
}
这是试图得到某个指定上界下的所有素数。但是它跑得很慢。 有什么建议吗

增加: 实际上,我想知道为什么这个程序运行得这么慢。这与如何计算素数无关

编辑: 更改了iPrime方法,首先从数学上过滤掉一些数字。
现在is的运行速度要快得多,在我的mac电脑上大约需要10秒才能计算到2000000

若要列出小于特定数的所有素数,应使用埃拉托斯坦筛。 它比你的算法快得多

你的算法太慢了,因为它会检查每个素数小于它的数,直到找到它的除数。因此,每个数字将至少用一个素数进行检查。 但当检查数增加时,素数列表也会增加,可能的检查数也会增加

经过多次检查后,将有数字被拒绝。 例如,在检查2,3,5,7,11,13后,数字26将被拒绝

此外,在检查所有较小的素数后,将接受每个素数


与您的算法相比,一旦将每个数字标记为“素数”或“非素数”,Eratosthenes算法的筛选将“接触”每个数字。

正如@rtruszk所提到的,从中重新发布的以下代码对于更大范围的Eratosthenes SoE的真正筛选将比您的代码运行得更快:

object SoE {
  def makeSoE_Primes(top: Int): Iterator[Int] = {
    val topndx = (top - 3) / 2
    val nonprms = new scala.collection.mutable.BitSet(topndx + 1)
    def cullp(i: Int) = {
      import scala.annotation.tailrec; val p = i + i + 3
      @tailrec def cull(c: Int): Unit = if (c <= topndx) { nonprms += c; cull(c + p) }
      cull((p * p - 3) >>> 1)
    }
    (0 to (Math.sqrt(top).toInt - 3) >>> 1).filterNot { nonprms }.foreach { cullp }
    Iterator.single(2) ++ (0 to topndx).filterNot { nonprms }.map { i: Int => i + i + 3 }
  }
}

上述代码主要是一种函数形式,使用尾部递归或高阶函数以及除用于快速筛选复合数的位集数组内容之外的不变性。它没有使用Java.util.BitSet那么快,但生成的代码稍微优雅一些。

检查这一点,您认为它运行得非常慢的依据是什么?有更快的方法,但你的方法似乎不是一种不合理的方法。花10秒找到200万的素数是很慢的,因为这样一个简单的任务,即使使用一个简单的基本的埃拉托什筛,也只需要10毫秒。部分原因是,模%运算所暗示的除法是现代CPU以10的CPU时钟周期进行的最慢的原始整数运算之一,而加法通常只需要CPU时钟周期的一小部分,甚至乘法也只需要大约一个时钟周期。Eratosthenes筛使用简单的基本操作来执行所有的内循环操作,每个循环只需几个时钟。谢谢!但据我所知,一旦forall方法不符合预测,它就会退出,对吗?然后primes.forall将在num%的第一个数字上退出_==0@StanleyShi,虽然您的程序只在找到一个等分的除数之前进行检查是正确的,但找到的每个素数都需要测试它是否被每个已找到的素数除法,直到其平方根为止。因此,平均而言,每个质数所做的工作量随着质数检查范围的增大而迅速增加。这与其他算法(如上文提到的Eratosthenes筛法)形成对比,在该算法中,每找到一个素数的工作量随着范围的增大而缓慢增加。