Суть в том, что вам придется измерить его самостоятельно для собственного приложения, чтобы увидеть, важно ли это.Вы можете получить довольно противоречивые результаты с текущей 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
}
}
}
Каждый должен распечатать 1000000000 в качестве ответа, а также времядолжно быть равно нулю (если JVM действительно умная) или примерно столько же, сколько нужно, чтобы добавить миллиард чисел.Но, по крайней мере, в моей системе Sun JVM оптимизирует в обратном направлении - повторные прогоны становятся медленнее - а абстрактные классы медленнее, чем черты.(Возможно, вы захотите запустить с java -XX:+PrintCompilation
, чтобы попытаться выяснить, что идет не так; я подозреваю, что зомби.)
Кроме того, стоит отметить, что scalac -optimise ничего не делает для улучшения ситуации - все зависит отJVM.
В отличие от JVM JRockit, он демонстрирует стабильную среднюю производительность, но, опять же, черты побеждают классы.Поскольку время согласовано, я сообщу о них: 3,35 с для классов (3,62 с для класса с оператором if) против 2,51 секунды для всех признаков, оператора if или нет.
(Iсчитаю, что эта тенденция в целом верна: Hotspot в некоторых случаях демонстрирует невероятно высокую производительность, а в других (например, в этом случае) запутывается и ужасно медленен; JRockit никогда не бывает супербыстрым - не пытайтесь получить C-подобныйпроизводительность даже из примитивов - но это редко приводит к ошибкам.)