Scala 中选项模式匹配何时优化至 if 语句?

问题描述 投票:0回答:1

这是

ifA
Option
函数,使用 if 语句编写:

def ifA[A](fcond: Option[Boolean])(ifTrue: Option[A], ifFalse: Option[A]): Option[A] =
  if (fcond.isDefined) {
    if (fcond.get) ifTrue
    else ifFalse
  } else None

这里是相同的函数,但 if 语句被模式匹配替换:

def ifA[A](fcond: Option[Boolean])(ifTrue: Option[A], ifFalse: Option[A]): Option[A] =
  fcond match
    case Some(true) => ifTrue
    case Some(false) => ifFalse
    case None => None

第一个更加优化,正如我从字节码中看到的那样,用 godbolt 编译,

scalac-3.0.0
链接到已编译的

我想编写像第二个这样的代码,但又不损失性能。那么,是否有任何 jvm 可以优化第二个代码到第一个代码?使用

scalac-3.0.0
编译的代码和新版本的
scalac
编译的代码有什么区别吗?

scala optimization compilation pattern-matching bytecode
1个回答
0
投票

正如评论所提到的,字节码简洁并不一定会转化为性能(尽管它会对性能产生一些影响)。这是因为诸如即时 (JIT) 编译为机器代码之类的技术可以由 JVM 在运行时针对代码的“热”部分完成。

了解什么更快的最好方法是使用像jmh这样的工具进行测量。为了方便在 Scala 中进行构建和基准测试,可以使用一个名为 sbt-jmh 的 sbt 插件。要对各种 JVM 进行基准测试,您需要在每个 JVM 中干净地编译和运行基准测试。

奇怪的是,您发布的行为也可以用另一种方式表达:

def ifF[A](fcond: Option[Boolean])(ifTrue: Option[A], ifFalse: Option[A]): Option[A] =
    fcond.flatMap { cond =>
        if (cond) ifTrue else ifFalse
    }

这会产生比第一个选项更短的字节码,并且至少与第二个选项一样符合 Scala 习惯。

© www.soinside.com 2019 - 2024. All rights reserved.