Если вы искренне заботитесь о написании сверхвысокопроизводительного кода (и вы можете думать , что вы делаете, но ошибаетесь в этом ), тогда классы типов причинят некоторую больследующие причины:
- Множество дополнительных вызовов виртуальных методов
- Вероятный бокс примитивов (например, при использовании классов типов скалаза для моноидов и т. д.)
- Создание объектов с помощью
def
которые необходимы, потому что функции не могут быть параметризованы - Создание объектов для доступа к «скрытым» методам
Во время выполнения JVM может оптимизировать некоторые ошибочные создания (например, созданиеMA
просто позвонить <*>
), но scalac
мало чем поможет.Вы можете увидеть это тривиально, скомпилировав некоторый код, который использует классы типов и используя -Xprint:icode
в качестве аргумента.
Вот пример:
import scalaz._; import Scalaz._
object TC {
def main(args: Array[String]) {
println((args(0).parseInt.liftFailNel |@| args(1).parseInt.liftFailNel)(_ |+| _))
}
}
А вот и код:
final object TC extends java.lang.Object with ScalaObject {
def main(args: Array[java.lang.String]): Unit = scala.this.Predef.println(scalaz.this.Scalaz.ValidationMA(scalaz.this.Scalaz.StringTo(args.apply(0)).parseInt().liftFailNel()).|@|(scalaz.this.Scalaz.StringTo(args.apply(1)).parseInt().liftFailNel()).apply({
(new anonymous class TC$$anonfun$main$1(): Function2)
}, scalaz.this.Functor.ValidationFunctor(), scalaz.this.Apply.ValidationApply(scalaz.this.Semigroup.NonEmptyListSemigroup())));
def this(): object TC = {
TC.super.this();
()
}
};
@SerialVersionUID(0) final <synthetic> class TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$2 extends scala.runtime.AbstractFunction0 with Serializable {
final def apply(): Int = TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$2.this.v1$1;
final <bridge> def apply(): java.lang.Object = scala.Int.box(TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$2.this.apply());
<synthetic> <paramaccessor> private[this] val v1$1: Int = _;
def this($outer: anonymous class TC$$anonfun$main$1, v1$1: Int): anonymous class TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$2 = {
TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$2.this.v1$1 = v1$1;
TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$2.super.this();
()
}
};
@SerialVersionUID(0) final <synthetic> class TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1 extends scala.runtime.AbstractFunction0$mcI$sp with Serializable {
final def apply(): Int = TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1.this.apply$mcI$sp();
<specialized> def apply$mcI$sp(): Int = TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1.this.v2$1;
final <bridge> def apply(): java.lang.Object = scala.Int.box(TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1.this.apply());
<synthetic> <paramaccessor> private[this] val v2$1: Int = _;
def this($outer: anonymous class TC$$anonfun$main$1, v2$1: Int): anonymous class TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1 = {
TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1.this.v2$1 = v2$1;
TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1.super.this();
()
}
};
@SerialVersionUID(0) final <synthetic> class TC$$anonfun$main$1 extends scala.runtime.AbstractFunction2$mcIII$sp with Serializable {
final def apply(x$1: Int, x$2: Int): Int = TC$$anonfun$main$1.this.apply$mcIII$sp(x$1, x$2);
<specialized> def apply$mcIII$sp(v1$1: Int, v2$1: Int): Int = scala.Int.unbox(scalaz.this.Scalaz.mkIdentity({
(new anonymous class TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$2(TC$$anonfun$main$1.this, v1$1): Function0)
}).|+|({
(new anonymous class TC$$anonfun$main$1$$anonfun$apply$mcIII$sp$1(TC$$anonfun$main$1.this, v2$1): Function0)
}, scalaz.this.Semigroup.IntSemigroup()));
final <bridge> def apply(v1: java.lang.Object, v2: java.lang.Object): java.lang.Object = scala.Int.box(TC$$anonfun$main$1.this.apply(scala.Int.unbox(v1), scala.Int.unbox(v2)));
def this(): anonymous class TC$$anonfun$main$1 = {
TC$$anonfun$main$1.super.this();
()
}
}
}
Вы видите, что здесь происходит огромное количество созданий объектов