Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Compiling like a boss! (With Triplequote Hydra)

Compiling like a boss! (With Triplequote Hydra)

We all love Scala, but the one aspect we have a hard time accepting are long compile times. It’s not uncommon for a project to experience compilation times of a handful of minutes, if not worse. On top of that, compilation times are unpredictable, depending on a combination of language features, external libraries, and type annotations. A single line change may increase compilation times ten fold.
What can we do? It’s paramount we gain greater insight into the tools and libraries we use. There are also established (anti-)patterns that you should know about, if you fancy to keep compilation times to a minimum. And why not utilizing all cores when compiling? The stock Scala compiler can’t do it, but Triplequote Hydra is here to change that. Sit tight and let’s cut down on compilation time!

Triplequote

May 14, 2017
Tweet

More Decks by Triplequote

Other Decks in Programming

Transcript

  1. Who are we? Mirco Dotta • Triplequote co-founder • Have

    been using Scala since 2005 • Eclipse Scala IDE committer (#3) • Contributed to Scala, Lagom, Play • Author of MiMa • Part of the founding Lightbend/Typesafe team Iulian Dragos • Triplequote co-founder • 13 years of Scala experience • Scala committer (#5) • Eclipse Scala IDE committer (#1) • SIP committee member • Part of the founding Lightbend/Typesafe team
  2. Agenda • State of Scala releases ◦ Is Scala getting

    any faster? • How to investigate long compile times ◦ Tips & Tricks • Parallelize compilation with Triplequote Hydra Compiler ◦ The free lunch!
  3. Scala releases & compilation speed • Scala 2.12 released in

    November 2016 • Drastically reduced binary footprint ◦ Runtime benefits! • Seems to have comparable performance wrt Scala 2.11 ◦ Shapeless tests take 20% more time compile (2.11.8 vs 2.12.1) ◦ Scala team noticed moderate speedup on their benchmarks ◦ ⇒ Hard to assess compilation speed of Scala releases • Good news: The Scala team is working on automated benchmarking! ◦ So we are good? Problem solved?
  4. Scala compiler options • The Scala compiler already gives you

    lots of useful options! • No brainers ◦ -Ywarn-unused ◦ -Ywarn-unused-import ◦ -Ywarn-dead-code ◦ -Ywarn-value-discard • Detective equipment ◦ -verbose ◦ -Xprint:<phase> (-Xshow-phases) ◦ -Xlog-implicits ◦ -Ymacro-debug-lite & -Ymacro-debug-verbose ◦ and others…
  5. Compile time by phase • Get a feeling of how

    much time each compiler phase consumes ◦ Use -verbose
  6. Compile time by phase • Get a feeling of how

    much time each compiler phase consumes ◦ Use -verbose Does typer take 50%+ of the whole compile time? Yes? Investigate!
  7. Let’s Investigate! • Usual suspects for long typechecking time ◦

    Macros ◦ Implicits ◦ Type Inference • Identify sources that take the most to compile: ◦ Hard without tooling help, but if you have a guess go for it ◦ Compile a single compilation unit (add the target folder in the classpath) ◦ If a compilation unit takes more time than expected to compile, inspect its AST with -Xprint:typer ▪ Scary amount of generated code? (hint: macros at play!) ▪ Complex/Long inferred types? ◦ Also use -Xlog-implicits ▪ Are there many implicits that are not applicable?
  8. Implicit Resolution imports package definitions local definitions orElse everything available

    without a prefix Map[ID, Employee] class Map[K, V] extends Seq[(K, V)] with Iterable[(K, V])... Implicit Scope of target type T
  9. Implicit Resolution imports package definitions local definitions orElse Implicit Scope

    of target type T Map[ID, Employee] class Map[K, V] extends Seq[(K, V)] with Iterable[(K, V])... everything available without a prefix
  10. Take away • Implicit resolution can be costly • Tip:

    Limit implicits in the scope ◦ Avoid import clauses bringing implicits in the scope ▪ Wildcard imports are bad ◦ Avoid defining implicits in the package object • Where should I place implicits? ◦ In the implicit scope! • Zalando tinbox project: ◦ Moving implicits defined in a package object into the implicit scope yielded a 40% compile time speedup! ◦ Interested in knowing more? Read https://tech.zalando.com/blog/achieving-3.2x-faster-scala-compile-time/
  11. Macro bittersweet • Macros can reduce boilerplate • Macros can

    be responsible for 80-90% of typechecking time ⇒ WOOOT! ◦ Macros can trigger expensive typechecking ◦ Watch out for implicit definitions that are implemented with a macro • Are you ok to trade productivity for code elegance? ◦ Be pragmatic: you may be better off maintaining some boilerplate code.
  12. Distribute Scala compiler • Distribute files to workers in the

    cloud (and gather results) • Hard problems: ◦ Inter-file dependencies ◦ It’s a distributed system
  13. Amdahl’s law How much speedup should we expect? p =

    percentage of parallelizable work s = speedup for parallelizable work (~ nr. of cores)
  14. Amdahl’s law Non-parallel covers everything that can’t be perfectly parallelized

    (JIT compilation, memory bus contention, penalty for inter-file dependencies) Non-parallel Max Speedup 50% 2x 40% 2.5x 30% 3.3x 20% 5x 10% 10x
  15. Hydra Today • Parallel Scala compiler ◦ Use the many

    cores we have! • Granularity? ◦ Parallelize at the CompilationUnit level ◦ Parallelize the whole phase pipeline (including typer!) • Hard problems ◦ Inter-file dependencies between workers ◦ Laziness and mutable state • Approach ◦ Share-nothing (use different compiler instances) ◦ ..but add back sharing when it’s safe
  16. How well does it work? Project Speedup specs2-core/test 2.5x specs2-common/main

    2.2x shapeless-core/js 1.58x shapeless-core/jvm 1.62x
  17. Triplequote Hydra Compiler • Based on Scalac ◦ We’re hoping

    this won’t be a fork forever • Drop-in replacement ◦ Not tied to Sbt, command line available • Supporting Scala 2.11.8+, 2.12.1+ ◦ May support older versions based on demand ◦ Other forks™ should work too • Run the community build ◦ Compare binary output ..standing on the shoulders of giants
  18. Insights • Monitor the build ◦ Build times across builds,

    commits or files ◦ Other metrics coming ▪ implicit uses, type inference steps, macro expansions, etc ▪ GC load on workers, time spent blocking, etc.
  19. Hydrate. Build. • Using Hydra → Add one line to

    your sbt build! addSbtPlugin("com.triplequote" % "sbt-hydra" % “<version>”) • Run sbt tasks as usual • Hydra takes care of parallel compilation • Sbt support ready • Support for other build tools (e.g., Gradle, Maven) based on demand
  20. Giving back to the community • Push patches upstream to

    Scala and Sbt/Zinc • Work well with Scala and Typelevel Scala • Triplequote will implement Scala SIP-25 ◦ @static fields and methods in Scala objects ◦ https://github.com/scala/scala-dev/issues/305
  21. Q2 2017 Q3 2017 Q4 2017 Private Roll-out General Availability

    Insights & Metrics Distributed Build Cloud Service
  22. Thanks! • Read how we helped Zalando achieving x3.2 faster

    compilation time https://tech.zalando.com/blog/achieving-3.2x-faster-scala-compile-time/ • Your company is interested in joining the private roll-out? ◦ Get in touch! [email protected] www.triplequote.com @triple_quote