scalaz / scalaz-plugin

A compiler plugin that will improve on the scala compiler on the assumption that the user is using the Scalazzi-safe subset of Scala.
GNU Lesser General Public License v3.0
73 stars 10 forks source link

Always inline syntax extensions #6

Open sir-wabbit opened 6 years ago

sir-wabbit commented 6 years ago

See https://github.com/typelevel/machinist and https://github.com/scalaz/scalaz/blob/series/8.0.x/meta/shared/src/main/scala/scalaz/meta/Ops.scala

sir-wabbit commented 6 years ago

For future docs:

Syntax extension inlining

Consider the following snippet:


implicit def eqList[A](implicit A: Eq[A]): Eq[List[A]] =
  new Eq[A] { ... }
implicit class EqOps[A](value: A) {
  def ===(other: A)(implicit A: Eq[A]): Boolean = A.equal(value, other)
}
...
object Test {
  def test: Unit = {
    val a : List[Int] = ...
    val b : List[Int] = ...

    for (i < 0 until 100) {
      a === b
    }
  }
}

The body of the loop will compile to:

new EqOps(a).===(b)(eqList(eqInt))

So there are two allocations per comparison, one allocation of the syntax extension class and one for the instance of Eq[List[A]]. This optimization should fix the former by inlining the syntax class methods,

object Test {
  def test: Unit = {
    val a : List[Int] = ...
    val b : List[Int] = ...

    for (i < 0 until 100) {
      eqList(eqInt).equal(a, b)
    }
  }
}