scala-dev
scala-dev copied to clipboard
Eliminate allocations of extension method providers
trafficstars
Allocations of classes providing extension methods should be eliminated.
Note that this problem is solved in many cases by value classes, for example 1 to 10 expands to Predef.intWrapper(10).to(20). After inlining intWrapper, we get RichInt.MODULE$.to$extension0(1, 10).
There are examples where the extension method provider is not a value class, like Ordering.Ops:
class Ordering[T] {
def lt(x: T, y: T)
class Ops(lhs: T) {
def <(rhs: T) = lt(lhs, rhs)
}
implicit def mkOrderingOps(lhs: T): Ops = new Ops(lhs)
}
object Ordering {
object Implicits {
implicit def infixOrderingOps[T](x: T)(implicit ord: Ordering[T]): Ordering[T]#Ops = new ord.Ops(x)
}
}
There are two ways to make the < extension method available:
def f[T: Ordering](x: T, y: T) = {
import Ordering.Implicits._
x < y
}
or
def f[T](x: T, y: T)(implicit ev: Ordering[T]) = {
import ev._
x < y
}
In both cases, an Ops instance is allocated. I haven't checked if we could turn Ops into a value class.
The https://github.com/typelevel/machinist macro exists for eliminating such allocations.