The scala.MbArray
class is an alternative implementation of the scala.Array
class
that does not require a scala.reflect.ClassTag
to be instantiated.
The scala.MbArray
class is an alternative implementation of the scala.Array
class
that does not require a scala.reflect.ClassTag
to be instantiated. On the other hand,
the locality and unboxing guarantees are still valid when used with the miniboxing
plugin. For example:
class C[@miniboxed T] {
val mb: MbArray[T] = MbArray.empty(100)
}
If the instatiation is done outside miniboxed code or cannot be optimized, the miniboxing
plugin will warn (don't forget to add the -P:minibox:warn
flag to your build!)
**Avoid the warnings at your own risk: You will lose the locality and unboxing guarantees!**
This annotation, used in code transformed by the miniboxing compiler plugin, will result in the function not being transformed to an optimized MiniboxedFunctionX, as would otherwise happen automatically
This annotation, used in code transformed by the miniboxing compiler plugin, will result in the function not being transformed to an optimized MiniboxedFunctionX, as would otherwise happen automatically
The http://scala-miniboxing.org website.
This annotation, used in code transformed by the miniboxing compiler plugin, will result in suppressing miniboxing warnings.
This annotation, used in code transformed by the miniboxing compiler plugin, will result in suppressing miniboxing warnings.
The http://scala-miniboxing.org website.
This annotation, used in code transformed by the miniboxing compiler plugin, will result in a lightweight specialization that gives good speedups while keeping the bytecode size from exploding.
This annotation, used in code transformed by the miniboxing compiler plugin, will result in a lightweight specialization that gives good speedups while keeping the bytecode size from exploding.
The http://scala-miniboxing.org website.
The MiniboxingReflection
object allows reflecting on the type parameters
of miniboxed classes.
The MiniboxingReflection
object allows reflecting on the type parameters
of miniboxed classes. For example, given class C[@miniboxed T]
, reflection
can determine at run-time whether a type parameter is miniboxed, its
instantiation and what type is used to store this value. These methods do
not incur any overhead, since they are compiled away by the miniboxing
plugin.
Let's see an example:
scala> import MbReflection._ import MbReflection._ scala> class C[@miniboxed T] { | override def toString: String = | s"C[T = ${reifiedType[T]}, miniboxed into a ${storageType[T]}]" | } defined class C scala> new C[Int] res4: C[Int] = C[T = int, miniboxed into a long] scala> new C[Unit] res5: C[Unit] = C[T = unit, miniboxed into a long] scala> new C[Float] res6: C[Float] = C[T = float, miniboxed into a double]
Yet, it's still possible to instantiate the class in an erased context, leading to suboptimal storage. Still, the miniboxing plugin will slap you on the wrist for doing so, and reflection will tell you you're doing it wrong:
scala> def newC[T] = new C[T] <console>:11: warning: The following code could benefit from miniboxing specialization if the type parameter T of method newC would be marked as "@miniboxed T" (it would be used to instantiate miniboxed type parameter T of class C) def newC[T] = new C[T] ^ newC: [T]=> C[T] scala> newC[Int] <console>:13: warning: The method newC would benefit from miniboxing type parameter T, since it is instantiated by a primitive type. newC[Int] ^ res3: C[Int] = C[T = reference, miniboxed into a reference]
Finally, there's a good use case for this, if the class is always supposed to be miniboxed:
scala> class D[@miniboxed T] { | assert(isMiniboxed[T], "Idiot!") | } define class D scala> new D[String] java.lang.AssertionError: assertion failed: Idiot! at scala.Predef$.assert(Predef.scala:165) ... 34 elided
The "isMiniboxed" method is also partially evaluated away by the compiler:
scala> def foo[@miniboxed T]: Unit = { | if (isMiniboxed[T]) | println("foo[miniboxed]") | else | println("foo[reference]") | } foo: [T]=> Unit scala> foo[Byte] foo[miniboxed]
In the low-level bytecode you will have:
def foo(): Unit = println("foo[reference]") def foo_J(...): Unit = println("foo[miniboxed]") def foo_D(...): Unit = println("foo[miniboxed]")
So there is 0 overhead in using the isMiniboxed
method. Still,
reifiedType
and storageType
are not partially evaluated and do incur
a small overhead.