How to find out what implicit(s) are used in my scala code
Asked Answered
C

2

8

Problem statement:

  • I read in multiple sources/articles that implicits drive up scala compilation time

  • I want to remove/reduce them to minimum possible to see what compilation time without them will look like (codebase is around 1000 files of various complexity based on scalaz & akka & slick)

  • I don't really know what kind of static analysis I can perform. Any liks/references to already existing tooling highly appreciated.

Celeriac answered 1/1, 2018 at 23:51 Comment(3)
Unless you more import 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.Black
@SarveshKumarSingh according to #5598585 it's more complex than that. That's why I'm after static code analysis.Celeriac
No. It is not. If you do not import anything, you will only have implicits from Scala.Predef._ in your scope. Other than this some collection methods locally import some implicits but those will be limited in method Scope. So as far as you are concerned if you do not import a implicit in your Scope, you will not be dealing with it. Also, if you have a function/def with signature like def 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
S
5

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)
Saleh answered 9/1, 2018 at 11:34 Comment(0)
C
0

There is scalac profiling being done by scala center now: https://scalacenter.github.io/scalac-profiling/

Celeriac answered 21/1, 2018 at 20:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.