It is true that implicits can degrade compilation speed, especially for code that uses them for type-level computations. It is definitely worth it to measure their impact. Unfortunately it can be difficult to track down the culprits. There are tools that can help though:
Run scalac with -Ystatistics:typer
to see how many tree nodes are processed during type-checking. E.g. you can check the number of ApplyToImplicitArgs
and ApplyImplicitView
relative to the total (and maybe compare this to another code base).
There is currently an effort by the Scala Center to improve the status quo hosted at scalacenter/scalac-profiling. It includes an sbt plugin that should be able to give you an idea about implicit search times, but it's still in its infancy (not published yet at the time of writing). I haven't tested it myself but you can still give it a try.
You can also compile with -Xlog-implicits
, pipe the output to a file and analyse the logs. It will show a message for each implicit candidate that was considered but failed, complete with source position, search type and reason for the failure. Such failed searches are expensive. You can write a simple script with your favourite scripting language (why not Scala?) to summarize the data and even plot it with some nice graphics.
Aside: How to resolve a specific implicit instance?
Just use reify
and good ol' println
debugging:
import scala.collection.SortedSet
import scala.reflect.runtime.universe._
println(showCode(reify { SortedSet(1,2,3) }.tree))
// => SortedSet.apply(1, 2, 3)(Ordering.Int)
implicits
, you are using only these from Scala Predef - scala-lang.org/api/2.12.0/scala/Predef$.html . You can keep them low by carefully importing only required implicits. – BlackScala.Predef._
in your scope. Other than this some collection methods locally import someimplicits
but those will be limited in method Scope. So as far as you are concerned if you do not import aimplicit
in your Scope, you will not be dealing with it. Also, if you have a function/def with signature likedef example(a: A...)(implicit x: X): Y
then you will either need the implicit in your scope or you will have to avoid using it. – Black