假设我有一个接受对象和列表的函数:
case class Point(x: Int, y: Int)
def f1(w: Point, l: List[String]) = { /* do something /* }
我通常会这样使用它:
val w = Point(1,1)
val lst = List("Hello", "world")
f1(w, lst) // non empty list
很多时候,我需要使用空列表作为第二个参数来调用该函数:
f1(w, List()) // empty list
f1(w, Nil) // empty list
最后两行之间是否有任何性能差异?
我认为使用List()
将调用List.apply()
方法。Scala编译器会对其进行优化Nil
吗?
这不是Scala的副本:Nil vs List()
注意:Nil
vs之间是否有任何性能差异List()
?Scala编译器在这里进行任何优化吗?
这样的课
import collections.immutable.List
class Test {
val l = List() // or Nil
}
编译他们两个,然后检查生成的字节码 javap -v
List()
给出:
5: getstatic #26 // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
8: putfield #14 // Field l:Lscala/collection/immutable/List;
并Nil
给出:
5: getstatic #24 // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
8: putfield #13 // Field l:Lscala/collection/immutable/Nil$;
因此,两者的字节码(和性能)相同。但是,可能还有其他选择的理由,正如戈文德在评论中所链接的问题中所述。
深入兔子洞:
查看源List()是List.apply()的糖,它是这样实现的:
def apply[A](xs: A*) = xs.toList
toList
来自TraversableOnce
和to[List]
隐式接受一个的调用CanBuildFrom[Nothing, A, List[A]]
,在这种情况下将是List.canBuildFrom
,而反过来来自ReusableCBF
,该构建器然后将用.apply()
,调用++= the empty array
,然后build()
对我来说,如何消除/转换成getstatic
forList()
还不是很清楚。(或者我在途中错过了一些聪明的东西)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句