scala案例类命名参数是否具有一些性能成本?

时间:2018-01-09 01:08:28

标签: scala

我发现在我的项目中使用它非常方便:

case class Thing(a: Option[String], b: Option[String], c: Option[String])
...
val a = Thing(a = Some("A"))
val b = Thing(b = Some("B"))
val c = Thing(b = Some("B"), c = Some("C"))

它实际上减少了许多丑陋的定义并且看起来很可读,但是现在我想知道这与它之间的性能/实现观点有什么不同吗?:

val a = Thing(Some("A"), None, None)
val b = Thing(None, Some("B"), None)
val c = Thing(None, Some("B"), Some("C"))

由于

1 个答案:

答案 0 :(得分:1)

从语义上讲,没有区别,因为None是一个单例对象。但是,从性能方面来说,我们可以看到在底层生成了什么类型的代码。

case class Thing(
  a: Option[String] = None,
  b: Option[String] = None,
  c: Option[String] = None
)

object Thing {
  def foo() = {
    val a1 = Thing(a = Some("A"))
    val b1 = Thing(b = Some("B"))
    val c1 = Thing(b = Some("B"), c = Some("C"))

    val a2 = Thing(Some("A"), None, None)
    val b2 = Thing(None, Some("B"), None)
    val c2 = Thing(None, Some("B"), Some("C"))
  }
}

我相信这是你要问的那种事情的一个例子。我们可以使用scalac Thing.java -Xprint:jvm编译它,以查看Scala编译器在删除所有语法糖之后剩下的内容。

val a1: Thing = new Thing(new Some("A"), Thing.apply$default$2(), Thing.apply$default$3());
val b1: Thing = {
  <artifact> val x$1: Some = new Some("B");
  <artifact> val x$2: Option = Thing.apply$default$1();
  <artifact> val x$3: Option = Thing.apply$default$3();
  new Thing(x$2, x$1, x$3)
};
val c1: Thing = {
  <artifact> val x$4: Some = new Some("B");
  <artifact> val x$5: Some = new Some("C");
  <artifact> val x$6: Option = Thing.apply$default$1();
  new Thing(x$6, x$4, x$5)
};
val a2: Thing = new Thing(new Some("A"), scala.None, scala.None);
val b2: Thing = new Thing(scala.None, new Some("B"), scala.None);
val c2: Thing = new Thing(scala.None, new Some("B"), new Some("C"));

因此使用命名语法可以引入一些中间变量。但函数调用本质上是模数堆栈空间的几个字节。更有可能的是,JIT会将这些编译成类似的代码片段,所以我说你几乎不用担心。