【发布时间】:2011-09-16 22:31:42
【问题描述】:
在 Scala 中,与其他可能的实现选择相比,使用隐式类型转换来增强类的功能是否会对 CPU 或内存产生重大影响?
例如,考虑一个愚蠢的字符串操作函数。此实现使用字符串连接:
object Funky {
def main(args: Array[String]) {
args foreach(arg => println("Funky " + arg))
}
}
此实现通过使用隐式类型转换隐藏了成员方法后面的串联:
class FunkyString(str: String) {
def funkify() = "Funky " + str
}
object ImplicitFunky {
implicit def asFunkyString(str: String) = new FunkyString(str)
def main(args: Array[String]) {
args foreach(arg => println(arg.funkify()))
}
}
两者都做同样的事情:
scala> Funky.main(Array("Cold Medina", "Town", "Drummer"))
Funky Cold Medina
Funky Town
Funky Drummer
scala> ImplicitFunky.main(Array("Cold Medina", "Town", "Drummer"))
Funky Cold Medina
Funky Town
Funky Drummer
有任何性能差异吗?一些具体的考虑:
Scala 是否内联对 asFunkyString 方法的隐式调用?
Scala 是否真的为每个 arg 创建了一个新的包装 FunkyString 对象,或者它可以优化掉额外的对象分配?
假设 FunkyString 有 3 种不同的方法(funkify1、funkify2 和 funkify3),并且 foreach 的主体依次调用每个方法:
println(arg.funkify1())
println(arg.funkify2())
println(arg.funkify3())
Scala 会重复转换 3 次,还是会优化掉多余的转换,每次循环迭代只做一次?
假设我在另一个变量中显式捕获转换,如下所示:
val fs = asFunkyString(arg)
println(fs.funkify1())
println(fs.funkify2())
println(fs.funkify3())
这会改变情况吗?
实际上,隐式转换的广泛使用是潜在的性能问题,还是通常无害?
【问题讨论】:
-
... 我在唱:“♫♩♬ 你为什么不直接测试一下?♫♩♬ 测量一下?♫♩♬ 做一百万次随机播放♫♩♬ "
-
由于原生代码和隐式代码之间的区别是如此缓慢,我们现在可以假设 scala 不会为每个调用创建一个新的包装器对象吗?因为在其他地方,这就是我听到的,但我不确定。也能回答您的其他问题会很有趣...
标签: performance scala implicit-conversion