_0 as defined is somehow causing extreme compile times
jdrphillips opened this issue · comments
Scala versions observed on: 2.13.8
, 2.13.9-bin-f11f1f7
The behaviour
This is a very bizarre thing I have noticed. If I use shapeless' definition of Nat
in calculations I can achieve very fast compile times on Sum
if I do not use shapeless' _0
Here is the code:
private[testing] object NatTest {
import shapeless.Nat
import shapeless.Succ
// Here is the code I swap out: Either use shapeless' _0 or define my own identical:
// import shapeless.nat._0
class _0 extends Nat with Serializable {
type N = _0
}
// Because I am using my own _0, I must define my own Sum. This is the same as shapeless' but typelevel only
trait Sum[A <: Nat, B <: Nat] { type Out <: Nat }
object Sum {
type Aux[A <: Nat, B <: Nat, Out0 <: Nat] = Sum[A, B] { type Out = Out0 }
implicit def zeroCase[A <: Nat]: Sum.Aux[_0, A, A] = ???
implicit def recursive[A <: Nat, B <: Nat](
implicit sum: Sum[A, Succ[B]]
): Sum.Aux[Succ[A], B, sum.Out] = ???
}
def sum[A <: Nat, B <: Nat](implicit s: Sum[A, B]): s.Out = null.asInstanceOf[s.Out]
// Some numbers I want to use:
type _12 =
Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[
_0
]]]]]]]]]]]]
type _15 =
Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[
_0
]]]]]]]]]]]]]]]
type _27 =
Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[
Succ[Succ[Succ[Succ[Succ[Succ[Succ[
_0
]]]]]]]]]]]]]]]]]]]]]]]]]]]
}
Note I am using shapeless' own Nat
and Succ
. I have had to define my own Sum
to use my own _0
, but it is the same algorithm shapeless uses. Note that my own definition of _0
is the same as shapeless, copy+pasted.
Here's the sum I am testing against:
sum[_15, _12]: _27
If I use shapeless.nat._0
the sum takes approx 120s to compile on my machine.
If I use NatTest._0
the sum takes approx 0-1s(!) to compile on my machine.
I have tried the following:
_0
defined in separate object_0
defined in separate package- Running my above code in a branch of
shapeless
itself (so not relying on a library jar)
I observe the same behaviour everywhere: shapeless.nat._0
causes 120x compile times compared to other scenarios
Scala versions observed on: 2.13.8
, 2.13.9-bin-f11f1f7
You can see the behaviour for yourself in my shapeless fork: https://github.com/jdrphillips/shapeless/blob/feature/nat-test/core/src/main/scala/shapeless/NatTest.scala
The expectation
I would expect my code to behave the same no matter where I defined _0
Resolved by using shapelss._0
and not the alias shapeless.nat._0