Description
Reproduction steps
- checkout https://github.com/KisaragiEffective/scala-match-on-huge-enum or https://github.com/KisaragiEffective/match-on-huge-enum-sealed-trait
- just compile
Problems
sbt:match-on-huge-enum> compile
[info] compiling 1 Scala source and 1 Java source to /private/tmp/scala-match-on-huge-enum/target/scala-2.13/classes ...
[warn] /private/tmp/scala-match-on-huge-enum/src/main/scala/Hello.scala:5:5: Cannot check match for unreachability.
[warn] The analysis required more space than allowed.
[warn] Please try with scalac -Ypatmat-exhaust-depth 40 or -Ypatmat-exhaust-depth off.
[warn] h match {
[warn] ^
[warn] 1 deprecation (since 2.13.0); re-run with -deprecation for details
[warn] two warnings found
[success] Total time: 163 s (02:43), completed Sep 17, 2023 10:14:55 PM
There are two issues.
- Each occurrence of the
match
expression adds a few minutes (originally reported as "3 or 4 minutes") to compilation time, which is non-negligible. - The current (2.13.12) compiler implementation takes too long time to find unreachable case (exhaustiveness performance issue is split: patmat does not consider that it is exhaustive even if it has wildcard arm #12874).
Notes
This is a performance problem: there is a case in real world.
One of them is in "Bukkit", a minecraft server, is providing API for plugging into Minecraft. It provides a class called Material
, which corresponds in-game item or block per one-by-one. As of today, there are 1866 entries.
Upon profiling we saw that scala.tools.nsc.transform.patmat.PatternMatching$OptimizeMatchTranslator.exhaustive
occupies ~85% of the CPU time (unreachableCase
also does ~15%, that's another story).
A work-around is to simply avoid match
on those enums (ours is avoided by GiganticMinecraft/SeichiAssist@1ad23ea, but preferred to use match
).
The above also applies to Scala 2's "pseudo" enum (sealed trait
+ object
). Some how its shorter (on my machine, its about half) than Java's one (but still slow).
If the match has only wildcard arm (or annotate scrutinee with @unchecked
, thank you @dwijnand) , it will not blow up.