Java compile speed vs Scala compile speed

27,681

Solution 1

The Scala compiler is more sophisticated than Java's, providing type inference, implicit conversion, and a much more powerful type system. These features don't come for free, so I wouldn't expect scalac to ever be as fast as javac. This reflects a trade-off between the programmer doing the work and the compiler doing the work.

That said, compile times have already improved noticeably going from Scala 2.7 to Scala 2.8, and I expect the improvements to continue now that the dust has settled on 2.8. This page documents some of the ongoing efforts and ideas to improve the performance of the Scala compiler.

Martin Odersky provides much more detail in his answer.

Solution 2

There are two aspects to the (lack of) speed for the Scala compiler.

  1. Greater startup overhead

    • Scalac itself consists of a LOT of classes which have to be loaded and jit-compiled

    • Scalac has to search the classpath for all root packages and files. Depending on the size of your classpath this can take one to three extra seconds.

    Overall, expect a startup overhead of scalac of 4-8 seconds, longer if you run it the first time so disk-caches are not filled.

    Scala's answer to startup overhead is to either use fsc or to do continuous building with sbt. IntelliJ needs to be configured to use either option, otherwise its overhead even for small files is unreasonably large.

  2. Slower compilation speed. Scalac manages about 500 up to 1000 lines/sec. Javac manages about 10 times that. There are several reasons for this.

    • Type inference is costly, in particular if it involves implicit search.

    • Scalac has to do type checking twice; once according to Scala's rules and a second time after erasure according to Java's rules.

    • Besides type checking there are about 15 transformation steps to go from Scala to Java, which all take time.

    • Scala typically generates many more classes per given file size than Java, in particular if functional idioms are heavily used. Bytecode generation and class writing takes time.

    On the other hand, a 1000 line Scala program might correspond to a 2-3K line Java program, so some of the slower speed when counted in lines per second has to balanced against more functionality per line.

    We are working on speed improvements (for instance by generating class files in parallel), but one cannot expect miracles on this front. Scalac will never be as fast as javac. I believe the solution will lie in compile servers like fsc in conjunction with good dependency analysis so that only the minimal set of files has to be recompiled. We are working on that, too.

Solution 3

You should be aware that Scala compilation takes at least an order of magnitude longer than Java to compile. The reasons for this are as follows:

  1. Naming conventions (a file XY.scala file need not contain a class called XY and may contain multiple top-level classes). The compiler may therefore have to search more source files to find a given class/trait/object identifier.
  2. Implicits - heavy use of implicits means the compiler needs to search any in-scope implicit conversion for a given method and rank them to find the "right" one. (i.e. the compiler has a massively-increased search domain when locating a method.)
  3. The type system - the scala type system is way more complicated than Java's and hence takes more CPU time.
  4. Type inference - type inference is computationally expensive and a job that javac does not need to do at all
  5. scalac includes an 8-bit simulator of a fully armed and operational battle station, viewable using the magic key combination CTRL-ALT-F12 during the GenICode compilation phase.

Solution 4

The best way to do Scala is with IDEA and SBT. Set up an elementary SBT project (which it'll do for you, if you like) and run it in automatic compile mode (command ~compile) and when you save your project, SBT will recompile it.

You can also use the SBT plug-in for IDEA and attach an SBT action to each of your Run Configurations. The SBT plug-in also gives you an interactive SBT console within IDEA.

Either way (SBT running externally or SBT plug-in), SBT stays running and thus all the classes used in building your project get "warmed up" and JIT-ed and the start-up overhead is eliminated. Additionally, SBT compiles only source files that need it. It is by far the most efficient way to build Scala programs.

Solution 5

The latest revisions of Scala-IDE (Eclipse) are much better atmanaging incremental compilation.

See "What’s the best Scala build system?" for more.


The other solution is to integrate fsc - Fast offline compiler for the Scala 2 language - (as illustrated in this blog post) as a builder in your IDE.

alt text

But not in directly Eclipse though, as Daniel Spiewak mentions in the comments:

You shouldn't be using FSC within Eclipse directly, if only because Eclipse is already using FSC under the surface.
FSC is basically a thin layer on top of the resident compiler which is precisely the mechanism used by Eclipse to compile Scala projects.


Finally, as Jackson Davis reminds me in the comments:

sbt (Simple build Tool) also include some kind of "incremental" compilation (through triggered execution), even though it is not perfect, and enhanced incremental compilation is in the work for the upcoming 0.9 sbt version.

Share:
27,681

Related videos on Youtube

user405163
Author by

user405163

Updated on April 30, 2020

Comments

  • user405163
    user405163 about 4 years

    I've been programming in Scala for a while and I like it but one thing I'm annoyed by is the time it takes to compile programs. It's seems like a small thing but with Java I could make small changes to my program, click the run button in netbeans, and BOOM, it's running, and over time compiling in scala seems to consume a lot of time. I hear that with many large projects a scripting language becomes very important because of the time compiling takes, a need that I didn't see arising when I was using Java.

    But I'm coming from Java which as I understand it, is faster than any other compiled language, and is fast because of the reasons I switched to Scala(It's a very simple language).

    So I wanted to ask, can I make Scala compile faster and will scalac ever be as fast as javac.

    • VonC
      VonC over 13 years
      Looks like some users agree with you ;) twitter.com/etorreborre/status/21286172202
    • Daniel C. Sobral
      Daniel C. Sobral over 13 years
      Go compiles faster than Java. Way faster, which is saying something.
    • Jeriho
      Jeriho over 13 years
      Ahaha, in my case it takes several minutes for average scalac compilation with few houndreds LOC, fsc is slightly faster.
  • VonC
    VonC over 13 years
  • Jackson Davis
    Jackson Davis over 13 years
    sbt can also do incremental compiles
  • VonC
    VonC over 13 years
    @Jackson: triggered execution, right! I have included it in my answer.
  • Elazar Leibovich
    Elazar Leibovich over 13 years
    I agree that it's not essential to have a rapid turn-around cycle. But it doesn't hurt, does it?
  • hansvb
    hansvb over 13 years
    I am not going to down-vote, but saying that you should adjust your working pattern to the limitations of your tool (the slow speed of the compiler) rather than trying to improve the tool is not a good argument. Especially the ability to do rapid test cycles is very valuable (even though it does not replace the need to do some deep thinking, the kind that is probably best done away from the keyboard, it does complement it nicely).
  • user405163
    user405163 over 13 years
    I think most of my productivity is actually lost to over thinking before running. I frequently find myself looking at some equation for long periods trying to spot what ever potential pitfall is waiting for me, all while I'm thinking, "Just run it!" in the back of my head. And sure enough, when I run the program I learn a lot more than I probably would have with another hour or two of meditation. Meditation is good, but I feel I had a very optimal use of incremental compiling/meditation with java.
  • user405163
    user405163 over 13 years
    I've switched from netbeans to ant+jedit(I know I know, ant is for cavemen, but I'll evolve on my own time) so that I can use fsc. But I was wondering, how does the compile speed of Clojure compare to Scala? It seems to have many of the features in Scala but I imagine the syntax is much easier to parse.
  • Daniel Spiewak
    Daniel Spiewak over 13 years
    You shouldn't be using FSC within Eclipse directly, if only because Eclipse is already using FSC under the surface. FSC is basically a thin layer on top of the resident compiler which is precisely the mechanism used by Eclipse to compile Scala projects.
  • Daniel Spiewak
    Daniel Spiewak over 13 years
    We're kinda getting off-topic here, but Clojure's compiler is blisteringly fast (much faster than javac on equivalent sources). You're right that it's a really simple language though, and it doesn't have any sort of static type system, which helps quite a bit.
  • Aaron Novstrup
    Aaron Novstrup over 13 years
    The IntelliJ IDEA Scala plugin also has an option to use fsc
  • Denis Tulskiy
    Denis Tulskiy over 13 years
    @anovstrup: yes, but it sometimes crashes.
  • hansvb
    hansvb over 13 years
    This is also similar to suggesting Shakespeare should not be using a spell-checker, and instead think harder about what he wants to say. The automated spell-checker helps with a completely different set of problems.
  • Elazar Leibovich
    Elazar Leibovich over 13 years
    @obox_lakes, hate to nitpick, but Java does need to do type inference for parameterized methods int a<T>(T a) {} and then a(pls_infer_my_type). james-iry.blogspot.com/2009/04/…
  • oxbow_lakes
    oxbow_lakes over 13 years
    @Elazar - yes, I know. But it is frankly laughable, next to scala, to call this "type inference"!
  • Ben McCann
    Ben McCann over 12 years
    FSC stands for Fast Scala Compiler - not Fast Java Compiler
  • VonC
    VonC over 12 years
    @BenMcCann: oops. Right. I have fixed the answer.
  • Mechanical snail
    Mechanical snail almost 12 years
    About the startup overhead due to class loading: would ahead-of-time compiling to native code using GCJ or Mono help?
  • marcus
    marcus over 10 years
    What if Scala were rewritten in C++? :o)
  • pedrofurla
    pedrofurla almost 8 years
  • João dos Reis
    João dos Reis over 7 years
    Would there be a benefit to using the invokedynamic bytecode instruction?