这是
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
编译的代码有什么区别吗?
正如评论所提到的,字节码简洁并不一定会转化为性能(尽管它会对性能产生一些影响)。这是因为诸如即时 (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 习惯。