We slow our build down by having a dozen 'tools'-projects with a handful of classes each in a straight dependency-line above our main project that contains 99% of the code. This easily increases our compile time from a few seconds to several minutes. With a bonus chance to cause an infinite IDE workspace build loop.
> Compiling 32,000 lines of code per second is not bad<p><a href="https://prog21.dadgum.com/47.html" rel="nofollow">https://prog21.dadgum.com/47.html</a>: <i>“By the mid-1990s, Borland was citing build times of hundreds of thousands of lines of source per minute”</i><p>I know it’s a different language, but I don’t think Java is significantly harder to parse than Pascal, bytecode doesn’t have to be heavily optimised (it gets heavily morphed at runtime) and computers are a lot faster than in the 1990s.<p>Also, recently (2020) <a href="https://news.ycombinator.com/item?id=24735366">https://news.ycombinator.com/item?id=24735366</a> said: <i>“Delphi 2 can compile large .pas files at 1.2M lines per second.”</i><p>Or am I mistaken in the idea that Java isn’t hard to parse? If so, why is it hard to parse? Annotations? Larger programs with lots of dependencies?
That's a nice writeup. Given the hot/cold difference you observe, I'd be very curious to see how builds compare when using maven daemon or gradle daemon.<p>I am not very familiar with those myself, simply aware of them.<p>[1] <a href="https://github.com/apache/maven-mvnd">https://github.com/apache/maven-mvnd</a><p>[2] <a href="https://docs.gradle.org/current/userguide/gradle_daemon.html" rel="nofollow">https://docs.gradle.org/current/userguide/gradle_daemon.html</a>
Interesting read. Just one remark to the "Keeping the JVM Hot" Benchmark:
Running the same Compilation Task on exactly the same input over and over again gives the Just in Time compiler of your Java runtime engine the chance to optimize for this specific task. This somehow spoils the idea of this benchmark because in a real world situation the source code changes between each compilation process.
Use Maven profiles:<p>* compile only<p>* compile/test only<p>* compile/install jar only, skip source/javadoc packages<p>* checkstyle only<p>* static analysis only<p>* code coverage only<p>* Skip PGP (you DO check your artifact signatures, right?)<p>The beauty of this is you can create a corporate super pom that defines all of these for you and they can be inherited by every project in your org.<p>Finally, if you have a large multi-module project, run with -T2C to parallel-ize module builds. If your tests are written in a sane/safe manner: -DuseUnlimitedThreads=true -Dparallel=classes -DforkCount=2C will also give you a major boost.<p>We have a giant code base (500,000 SLOC) with 28 maven modules, and a full compile and install takes less 40 seconds with compile/install only. You often don't need to do a full build, but even with tests thats about 3 mins on a M3 Max.
> Again, Maven doesn’t make it easy to show the classpath used to call javac ourselves.<p>Wait, I was under the impression that maven dependency plugin has a command for exactly that (dependency:build-classpath or something like that)?
Seems easy enough to do a quick fix for. Just add a option to maven that goes straight into compile and does nothing else. Would be good for local dev. However as we all know maven does much more than this and server side ci/cd process is what really slows your other team members down (if its slow)