Hacker News new | past | comments | ask | show | jobs | submit login

Thats last few sentences make no sense. The argument is that uptake is stunted by the JVM's slow startup time, making it unsuitable for commandline utils or desktop apps. However thats easily fixed which was never more hillariously stated than when Rich Hickey did it a decade ago. A blogpost went viral and it was a thunderous critique of Clojure, focused on this single point of slow start up. In the comment section was only 1 reply from Rich:

time java -client -jar clojure.jar helloworld.clj

> system time 0.0001s

The -client param makes all the difference :)




For anyone else wondering, "holy crap, WTF does -client do?" here you go: https://stackoverflow.com/a/198651/931209

And to save folks a click:

> The Client VM compiler does not try to execute many of the more complex optimizations performed by the compiler in the Server VM, but in exchange, it requires less time to analyze and compile a piece of code. This means the Client VM can start up faster and requires a smaller memory footprint.

There's literally so many just insane things about the JVM and its variants, I totally get why some folks are like "JAVA OR DEATH." I just wish I had started learning it 20 years ago, like a lot of 'em, so it wasn't such a gigantic wall of pedantic knowledge to acquire.


> A 64-bit capable JDK currently ignores this option and instead uses the Java Hotspot Server VM.


This is an extremely important detail, as I expect pretty much everyone to run the 64bit version of the JVM.


Uhm.. I want to give the benefit of the doubt, but frankly this seems deceptive, or at least out of date, unless I'm totally missing something.

Why is there no magical --client / --script option for the Clojure ClI to make startup faster, if this is such an easy solution? Also, you show system time, but the time to load dependencies is in user time, which is slow by the nature of Clojure.

Example:

    $ time java -client -classpath /usr/local/Cellar/clojure  /1.10.1.492/libexec/clojure-tools-1.10.1.492.jar clojure.main hello.clj
    Hello, world
    java -client -classpath  clojure.main scripts/script.clj    1.39s user 0.08s system 187% cpu 0.788 total

    $ time java  -classpath /usr/local/Cellar/clojure/1.10.1.492/libexec/clojure-tools-1.10.1.492.jar clojure.main hello.clj
    Hello, world
    java -classpath  clojure.main scripts/script.clj  1.37s user 0.09s system 180% cpu 0.811 total
(Excuse the details of my Clojure install location above)

User time appears slightly slower without the -client option, but probably is not statistically significant. Also, anyone who has worked on more than a toy project with Clojure knows that it's not just about the Hello World startup speed, every dependency you add has a significant impact on Clojure startup time.


As mentioned in other comments, the -client option is ignored on 64 bit JVMs, so it has no practical effect. Giving the benefit of doubt, Rich Hickey must have been using a 32 bit JVM.


That's not quite it. The client/server distinction was removed from the JVM many years ago. These days the JVM switches between modes on the fly on a per-method basis, this is called tiered compilation, so the optimisations are in effect on by default. Back in 2006 yes it may have made a big difference but it wouldn't have made startup magically instant.

IIRC Clojure apps are slow to start because they do a lot of first-time setup work that isn't actually executing user code. It's not so much a JVM problem as a Clojure-emitted-code problem. The GraalVM native-image tool fixes it because it can start an app in a pre-initialised state.


I understand, but either way, the example Rich Hickey used to execute the sample Clojure application in less than a millisecond seems impossible?

In other words, if Rich' example is real and recent, what could possibly be the environment in which this worked?


Yeah. Not sure - maybe it dates from a time when clojure was just a toy or prototype or something.


For me, scripts and command line application startup time is mostly a solved problem. You can just use ClojureScript, Babashka or Joker for scripting and CLI apps that don't need to perform too much CPU bound work. And for CPU intensive CLI apps, you can now use Graal's SubstrateVM to have a native build which starts instantly.


This is what I am referring to: http://clojure-goes-fast.com/blog/clojures-slow-start/

> As it turns out, Clojure start time is a complicated and multi-dimensional topic. Clojure projects are slow to start not only because of JVM — JVM itself starts in ~50 ms — but because of JVM specifics the classes are loaded slowly. Clojure projects are slow to start not only because of Clojure — Clojure itself starts in ~1 second — but because of Clojure specifics, the namespaces, especially not AOT-compiled one, are loaded slowly. And so on.


According to the latest status update from a member of the Clojure core team [1], we may see improvements in startup time with the next version of Clojure (1.11).

[1] https://insideclojure.org/2020/02/28/journal/


Running a simple cli application written in clojure with the help switch ensuring it doesn't do much beyond print text.

With and without -client 1 second

Built with graal 22 ms




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: