Being aware that Range is slow compared to a loop under Scala2, I migrated the benchmark to Scala3, and observed a horrible downgrade in performance in case of Range class.
Note that while loop time is comparable .
My questions:
- Is my benchmark correct?
- Did Range implementation change under Scala3 and performance hit is to be expected?
Scala2:
while loop time: 0.015882699999999996 ms
range loop time: 0.20659249999999996 ms
Scala3:
while loop time: 0.011921900000000001 ms
range loop time: 464.97765689999994 ms
Benchmark code:
package scalashop
import org.scalameter.{Key, Warmer, config}
object TestDoubleLoopPerformance {
val standardConfig = config(
Key.exec.minWarmupRuns := 5,
Key.exec.maxWarmupRuns := 10,
Key.exec.benchRuns := 10,
// Key.verbose := true
) withWarmer(Warmer.Default())
def main(args: Array[String]): Unit = {
val whileLoopTime = standardConfig measure {
for (iter <- 0 to 100) {
sumWithWhileLoop(1000, 2000)
}
}
println(s"while loop time: $whileLoopTime")
val rangeLoopTime = standardConfig measure {
for (iter <- 0 to 100) {
sumWithRange(1000, 2000)
}
}
println(s"range loop time: $rangeLoopTime")
}
private def sumWithRange(xEnd: Int, yEnd: Int) = {
var sum = 0
for {
x <- 0 until xEnd
y <- 0 until yEnd
} sum += 1
sum
}
private def sumWithWhileLoop(xEnd: Int, yEnd: Int) = {
var sum = 0
var x = 0
while (x < xEnd) {
var y = 0
while (y < yEnd) {
sum += 1
y += 1
}
x += 1
}
sum
}
}
Environment:
- JVM: openjdk 11.0.9.1
- Scalameter: 0.21