> Then someone in your team failed learning the bare minimum to write a sane gradle file
Then someone in over 15 years and 8 versions gradle failed to make a system that doesn't require "learning to write sane gradle files" to make sure that it's only two orders of magnitude and not five orders of magnitude slower than it can be.
> and are putting imperative stuff into the configuration phase
Has nothing to do with the slowness that is gradle.
> For big projects, compiling only what’s necessary is a huge time win.
Build systems are a complex problem. Like, you can compare it to cargo/go’s build system etc, but these forget about 90% of the problem, and come up with a hard-coded for the happy-path rust/go project, with zero non-native dependency, all downloaded from the repository. This is not a bad thing, don’t get me wrong. But it is not enough to compile, say, a browser.
Meanwhile, there are only a couple, truly general build systems, all of them quite complex — as you can’t get away with less. Gradle and bazel are pretty much the only truly generic build systems (I’m sure there are a couple more, but not many). You can actually compile a mixed java, c++, whatever project with gradle, for example, just fine, with proper parallelism, caching, etc.
As for your points:
> in 15 years is still slow by default
Absolutely false. A 3-4 lines gradle build file for java will be fast, and correctly parallelize and maximally utilize previously built artifacts.
> in 15 years could not acquire any sensible defaults that shouldn't need extra work to configure
It’s literally 4 lines for a minimal project, maybe even less. I’m getting the feeling that you have zero idea about what you talk about.
> is written in an esoteric language with next to zero tools to debug and introspect
I somewhat agree, though nowadays kotlin is also an alternative with strong typing, proper auto-complete, the only trade off is a tiny bit slower first compile of the config file. Also, both could/can be debugged by a normal java debugger.
> randomly changes and moves thing around every couple of years for no discernible reason
There is some truth to this. But the speed has definitely improved.
> has no configuration specification
Kotlin is statically typed. Also, the API has okayish documentation, people just like to copy-paste everything and wonder why it fails. You wouldn’t be able to fly a plane either from watching 3 sitcoms showing a cockpit, would you?
> Absolutely false. A 3-4 lines gradle build file for java will be fast, and correctly parallelize and maximally utilize previously built artifacts.
I've never seen this on any project that utilizes gradle. Every time, without fail, it's a multi-second startup of gradle that eventually invokes something that is actually fast: javac.
> I’m getting the feeling that you have zero idea about what you talk about.
Only 7 years dealing with java projects, both simple and complex
>> has no configuration specification
> Kotlin is statically typed.
Kotlin being statically typed has literally nothing to do with a specification.
Becuase Gradle doesn't have a configuration. It has a Groovy/Kotlin module that grew organically, haphazardly and without any long term plans. So writing gradle configuration is akin to reverse-engineering what the authors intended to do with a particular piece of code or API.
> Also, the API has okayish documentation
"okayish" is a synonim for bad. You'd think that a 15-year project in its 8th major version would have excellent API documentation
> people just like to copy-paste everything and wonder why it fails. You wouldn’t be able to fly a plane either from watching 3 sitcoms
So, a project with no specification to speak of, with "okayish" API that is slow as molasses by default out of the gate [1] keeps blaming its users for its own failure because somehow it's a plane, and not a glorified overengineered Makefile.
[1] A reminder, if you will, that gradle managed to come up with caching configs to speed up its startup time only in version 8, after 15 years of development.
It has always been “an imperative code that outputs the declarative configuration that can be used for the build”. Which is a very reasonable thing to do, but unfortunately most people fail to understand that a println in the config file’s global scope is different than inside a closure for a task description.
> but unfortunately most people fail to understand that a println in the config file’s global scope is different than inside a closure for a task description.
Literally no one complaining about gradle being slow is doing that. Allmost all of gradle's problems come not from people using it, but from Gradle itself.
I mean, you said it yourself: in 15 years the state of their API docs is "okayish". But somehow people are still expected to make sense of this shit because apparently it's a plane? But planes famously have extensive documentation, and procedures, and decades of expertise available. Exactly unlike gradle.
It could be if tool is work of good design and engineering. But not when tool's claim to fame is that it does not use XML to describe build config like Maven/Ant.
There are not many alternatives that are truly general build tools (not limited to single language/repository, etc), and properly parallelize and cache.
What step are we talking about? Javac itself is absolutely on the same order of magnitude speed as Go per loc, while rust is significantly slower (which makes sense, the latter is a properly optimizing compiler with heavy static analysis, while the former two just spews out java byte code/machine code).
Gradle with a daemon is also pretty fast, you are just probably used to some complex project with hundreds of dependencies and compare it to a cargo file with a single dependency.
Just a nitpick, but the static analysis in Rust doesn’t account for most of why compilation is slow, as proven by the fact that cargo check is much faster than cargo build.
Yeah, I know. I believe it’s mostly the amount of LLVM IR that is the problem (e.g. each generic instantiation outputs by default a new copy of roughly the same code), isn’t it?
> Javac itself is absolutely on the same order of magnitude speed as Go per loc
Not really when it has to run on a cold JVM. And before it warms up, it’s already done.
Then you are in territory of keeping the compiler process between the runs, but that is a memory hog and also not always realiable (gradle often decides to run a fresh daemon for whatever reason).
So theoretically, in lab conditions yes, in practice no.
> while rust is significantly slower
Everybody repeats that but there is surprisingly little evidence in form of benchmarks. I can see rustic compiles over 50k Loc per second on average on my M2, which is roughly the same order of magnitude as Java. And checking without building is faster.
I've yet to see a project where Gradle daemon a) does anything useful and b) is acutally used by gradle itself (instead of seemingly doing everything from scratch, no idea what it does in the seconds it takes for it to start up).
>I've yet to see a project where Gradle daemon a) does anything useful
Also my experience.
Only using Gradle deamon does not help making a multi-project setup much faster. You also have to enable build cache, configuration cache and configure on demand with `--configuration-cache --configure-on-demand` and hope nobody in the project breaks the ability for Gradle to use these caches. But then it still took at least 10 seconds to build and start my services (and that's with incremental builds, like you changed one line of code after the first slow build). I spend two days and more after release to speed this stuff up, before it was 30 seconds sometimes 60 seconds.
And the protobuf Gradle plugin sometimes did not update the generated code, so you had force-delete the files on every build. And then other stuff in the caches broke and you had to delete `.gradle` directory and sometimes even the `~/.gradle` directory. And sometimes the Gralde daemon hangs so you have to force it to stop with `--stop.
Go build, deno and bun are so much more reliable and faster. Something that was surprisingly fast was using the Gradle setup with skaffolding. Java hot code swapping is very fast.
This. Gradle wastes tremendous amounts of time on non-compile tasks. So even if Java takes a few seconds to compile, the whole build is often much, much longer. Interestingly, my impression is that maven is significantly more snappy.
> gradle is faster as a build tool for incremental compilation
Implicit:
> …than it is building from scratch, where it needs to download lots of stuff
I mean, yes, saying Java builds are fast does seem a bit “rolls eyes, yes technically by loc when the compiler is actually running” …but, ^_^! let’s not start banging on about how great cargo/rust compile times are… they’re really terrible once procedural macros are used, or sys dependencies invoke some heinous c dependency build like autoconf and lots of crates do… and there’s still a subpar incremental compilation story.
So, you know. Eh. Live and let live. Gradle isn’t that bad.
So maybe I was just unlucky with gradle and lucky with cargo. A project that is a mixture of 20k LoC Scala and 300k LoC Java took 6 minutes to compile, and incremental was still several tens of seconds. Cargo/Rust cold compiles a project of 1M LoC (all dependencies) in about 1:30 on the same hardware and incremental is like 2-4 seconds.
As for precedural macros - yes they can be slow to compile but so are Java annotation processors.
Scala is a much different case, it has one of the most advanced type systems, many implicit scoping rules etc. Even a java change that might affect the scala codebase could result in a slow incremental build. Also, the build system may not have been as modular as it could.
In my experience, java annotations gets processed very fast.
Well, that's a bit of a stretch. It is definitely one of the most complex type systems due to interactions between nominal sub-typing and type classes which is a bit hairy. But in terms of what this type system can express or prove, it's both inferior (cannot express lifetimes or exclusive access) and superior (HKTs, path dependent types) to Rust in some aspects. Let's say they are close.
Scala is the problem here. Scala has several issues filed for slow compilation.
300K LOC Java should be done within ~1.5 minutes flat from zero. Can be even faster if you are running maven daemon for example. Or even within ~30 seconds if everything is within one module and javac is only invoked once.
(Also, gradle is faster as a build tool for incremental compilation)