底线是,你将不得不为自己的应用程序自己测量它,看它是否重要。您可以通过当前的JVM获得相当违反直觉的结果。尝试一下。
文件TraitAbstractPackage.scala
package traitvsabstract
trait T1 { def x: Int; def inc: Unit }
trait T2 extends T1 { def x_=(x0: Int): Unit }
trait T3 extends T2 { def inc { x = x + 1 } }
abstract class C1 { def x: Int; def inc: Unit }
abstract class C2 extends C1 { def x_=(x0: Int): Unit }
abstract class C3 extends C2 { def inc { x = x + 1 } }
文件TraitVsAbstract.scala
object TraitVsAbstract {
import traitvsabstract._
class Ta extends T3 { var x: Int = 0}
class Tb extends T3 {
private[this] var y: Long = 0
def x = y.toInt
def x_=(x0: Int) { y = x0 }
}
class Tc extends T3 {
private[this] var xHidden: Int = 0
def x = xHidden
def x_=(x0: Int) { if (x0 > xHidden) xHidden = x0 }
}
class Ca extends C3 { var x: Int = 0 }
class Cb extends C3 {
private[this] var y: Long = 0
def x = y.toInt
def x_=(x0: Int) { y = x0 }
}
class Cc extends C3 {
private[this] var xHidden: Int = 0
def x = xHidden
def x_=(x0: Int) { if (x0 > xHidden) xHidden = x0 }
}
def Tbillion3(t: T3) = {
var i=0; while (i<1000000000) { t.inc; i+=1 }; t.x
}
def Tbillion1(t: T1) = {
var i=0; while (i<1000000000) { t.inc; i+=1 }; t.x
}
def Cbillion3(c: C3) = {
var i=0; while (i<1000000000) { c.inc; i+=1 }; c.x
}
def Cbillion1(c: C1) = {
var i=0; while (i<1000000000) { c.inc; i+=1 }; c.x
}
def ptime(f: => Int) {
val t0 = System.nanoTime
val ans = f.toString
val t1 = System.nanoTime
printf("Answer: %s; elapsed: %.2f seconds\n",ans,(t1-t0)*1e-9)
}
def main(args: Array[String]) {
for (i <- 1 to 3) {
println("Iteration "+i)
val t1s,t3s = List(new Ta, new Tb, new Tc)
val c1s,c3s = List(new Ca, new Cb, new Cc)
t1s.foreach(x => ptime(Tbillion1(x)))
t3s.foreach(x => ptime(Tbillion3(x)))
c1s.foreach(x => ptime(Cbillion1(x)))
c3s.foreach(x => ptime(Cbillion3(x)))
println
}
}
}
每个人都应该打印出10亿的答案,而且所花费的时间应该是零(如果JVM是很聪明)或约需要添加十亿个数字。但至少在我的系统中,Sun JVM向后优化 - 重复运行速度变慢 - 而抽象类比特性慢。 (你可能想用java -XX:+PrintCompilation
来试图弄清楚出了什么问题;我怀疑是僵尸)。
另外,值得注意的是scalac -optimise没有任何改进的地方 - 这一切都取决于JVM。
相比之下,JRockit JVM的性能始终如一,但同样,特质击败了类。由于时间是一致的,我会报告他们:3.35s的类(3.62s为一个if语句)与2.51秒的所有特性,if语句或否。 (我发现这种趋势总体上是真实的:在某些情况下,热点产生快速的性能,而在其他情况下(例如这种情况),会变得困惑并且非常慢; JRockit从不超速 - 不要打扰试图从原语中获得类似C的性能 - 但它很少出现错误)。
如果您正在认真考虑这种低级优化,那么您正在使用错误的编程语言。 – Raphael 2011-02-10 21:37:48
@Raphael如果您在Android系统或类似系统上使用Scala,您可能需要注意所有那些您通常不会重复考虑的事情。 – wheaties 2011-02-10 21:54:59