You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么Scala 3中用while循环填充Array[Int]比Array.fill慢100倍?

Scala 3 手动while循环填充数组性能异常问题说明

我实现了两种填充Array[Int]的方式,测试结果如下。第一种执行耗时84ms,第二种速度慢100倍:

Execute 'filling via Array.fill' in 84 ms
Execute 'filling via while' in 8334 ms

为什么第二种实现耗时高100倍?这不是GC导致的,我去掉第一个执行逻辑后,第二个的耗时依然不变。测试环境为Scala 3、Java 11,执行命令如下:

.jdks/adopt-openjdk-11.0.11/bin/java ... Fill

另外如果查看Array.fill的实现,会发现它底层也是通过while实现的,完整测试代码如下:

object Fill extends App {
  def timeMeasure[R](name: String)(block: => R): R = {
    val startTime = System.currentTimeMillis()
    val r = block
    val endTime = System.currentTimeMillis()
    println(s"Execute '$name' in ${endTime - startTime} ms")
    r
  }

  val n = 1000 * 1000 // * 10
  var ar = timeMeasure("filling via Array.fill") {
    Array.fill[Int](n)(10)
  }
  ar = timeMeasure("filling via while") {
    val array = new Array[Int](n)
    var i = 0
    while (i < n) {
      array(i) = i
      i += 1
    }
    array
  }
}

PS:我在Scala 2.12上重复了该测试,结果如下:

Execute 'filling via Array.fill' in 118 ms
Execute 'filling via while' in 6 ms

因此可以确定问题出在Scala 3上。

PPS:该场景下使用for (i <- 0 until n)的速度正常,耗时和Scala 2.12的表现一致。但也有部分场景下for循环的速度比while慢2到3倍。

PPPS:针对认为这是随机误差的观点,我可以确认不是:我执行了100次测试,总耗时516秒(测试当天我的PC运行速度更快),平均耗时仍然很高。而且部分程序中的代码块只会执行一次,并非所有性能测试都适合取平均耗时。

更新:我发现当val n定义在代码块外部时,执行速度会慢约1000倍,目前暂不清楚背后的原因,该问题已在Scala 3编译器仓库有相关讨论。

内容的提问来源于stack exchange,提问作者Mikhail Ionkin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 15:18:03