object E7 {
def next_prime(primes: List[Int]) = primes match {
case ps@(h :: t) => {
// Version 1
val rpq = ps.reverse.exists _
// Version 2
val rpq = ps.reverse.exists(_)
(Iterator.from(h + 1).find((v) => ! rpq(v % _ == 0)): @unchecked) match {
case Some(v) => v :: ps
}
}
case Nil => List(2)
}
val primes = Iterator.iterate(List[Int]())(next_prime)
def main(args: Array[String]) {
println(primes.drop(20001).next.head)
}
}
First version takes 3.6s to complete, second - 19.3s! What's the difference?
Edit: Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_21)
The first one is interpreted as
{ val temp = ps.reverse; (x: Int) => temp.exists(x) }
while the second one is interpreted as
(x: Int) => ps.reverse.exists(x)
This explains the difference: you have to reverse each time in the second case, but only once in the first. I am not sure where in the spec it says that this is what you get in each case (or if it does).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With