The heavyweight framework (and startup cost) that comes with Java and C# makes them challenging for widely-adopted lightweight command-line tools. (Although I love C# as a language, I find the Rust toolchain much simpler and easier to work with than modern dotnet.)
Building C (and C++) is often a nightmare.
Do you mean the VM/runtime? If so, you might be able to eliminate that with an AOT build.
> I find the Rust toolchain much simpler and easier to work with than modern dotnet
What part of the toolchain? I find them pretty similar with the only difference being the way you install them (with dotnet coming from a distro package and Rust from rustup)
1) dynamic loading of jar files
2) reflection
Number 1 allows you to load arbitrary jar files with code and execute them. Number 2 allows you to programmatically introspect existing code and then execute logic like "Find me all Foo sub classes and create an instance of those and return the list of those objects". You can do that at any time but a lot of that kind of stuff happens at startup. That involves parsing, loading and introspecting thousands of class files in jar files that need to be opened and decompressed.
Most of "Java is slow" is basically programs loading a lot of stuff at startup, and then using reflection to look for code to execute. You don't have to do those things. But a lot of popular web frameworks like Spring do. A lot of that stuff is actually remarkably quick considering what it is doing. You'd struggle to do this in many other languages. Or at all because many languages don't have reflection. If you profile it, there are millions of calls happening in the first couple of seconds. It's taking time yes. But that code has also been heavily optimized over the years. Dismissing what that does as "java is slow" and X is fast is usually a bit of an apples and oranges discussion.
With Spring Boot, there are dozens of libraries that self initialize if you simply add the dependency or the right configuration to your project. We can argue about whether that's nice or not; I'm leaning to no. But it's a neat feature. I'm more into lighter weight frameworks these days. Ktor server is pretty nice, for example. It starts pretty quickly because it doesn't do a whole lot on startup.
Loading a tiny garbage collector library on startup isn't a big deal. It will add a few microseconds to your startup time maybe. Probably not milliseconds. Kotlin has a nice native compiler. If you compile hello world with it it's a few hundred kilobytes for a self contained binary with the program, runtime, and the garbage collection. It's not a great garbage collector. For memory intensive stuff you are better off using the JVM. But if that's not a concern, it will do the job.
Want fast startup for an Azure Function talking to Azure SQL Database? Hah… no.
In all seriousness, that one dependency is the chain around the ankle of modern .NET because it’s not even fully async capable! It’s had critical performance regression bugs open for years.
Microsoft’s best engineers are busy partying in the AI pool and forgot about drudgery like “make the basics components work”.
Java starting slowly is mostly from all the cruft in the typical java app, with springboot, dependency injection frameworks, registries etc. You don't have to have those, it's just that most java devs use them and can't conceive of a world of low dependencies
Still not great for commandline apps, but java itself is much better than java devs
In contrast, "time" reports that rust takes 1ms, which is the limit of it's precision.
Python does Hello World in just 8ms, despite not having a separate AOT compilation step.
The general guidance I've seen for interaction is that things start to feel laggy at 100ms; so 30ms isn't a dealbreaker, but throwing a third of your time budget at the baseline runtime cost is a pretty steep ask.
If you want to use the application as a short lived component in a larger system, than 30ms on every invocation can be a massive cost.
To avoid manually writing all the Panama boilerplate, you can instead write a C header file with the desired types, and then run jextract through it.
At least not for Graal.
https://stackoverflow.com/questions/75316542/why-do-i-need-j...
As you can see, it has nothing to do with that Stack Overflow question,
https://www.graalvm.org/jdk25/reference-manual/native-image/
> I think what you actually want to do, is to compile a native image of your program. This would include all the implications like garbage collection from the JVM into the executable.
And it is this "native image" that all the comments above in this thread have been discussing, not JEP 295. (And Graal-based AOT in native images does remove the need to bundle a whole JRE.)