Reputation: 603
Here is the ifA
function for Option
, written using if-statements:
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
And here is the same function, but if-statements replaced by pattern matching:
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
The first one is more optimized, as I can see from the bytecode, compiled with godbolt with scalac-3.0.0
, link to compiled.
I want to write code like the second, but not loosing performance. So, are there any jvm's, that optimizes the second code up to first one? And is there any difference between this code compiled with scalac-3.0.0
and newer versions of scalac
?
Upvotes: 0
Views: 61
Reputation: 452
As comments have mentioned, bytecode terseness does not necessarily translate to performance (although it will have some bearing on it). This is because of techniques such as Just-In-Time (JIT) compiling to machine code that can be done by the JVM during runtime for "hot" parts of the code.
The best way to understand what is faster is to measure with a tool like jmh. For convenience building and benchmarking in Scala, there is a plugin for sbt called sbt-jmh that can be used. To benchmark various JVMs you would need to cleanly compile and run your benchmarks in each.
Curiously, the behaviour you've posted could also be expressed in another way:
def ifF[A](fcond: Option[Boolean])(ifTrue: Option[A], ifFalse: Option[A]): Option[A] =
fcond.flatMap { cond =>
if (cond) ifTrue else ifFalse
}
Which results in even shorter bytecode than the first option, and is at least as Scala idiomatic as your second option.
Upvotes: 1