How long does Clojure start-up really take? Let’s find out.
Get yourself a Clojure project. Download the dependencies and pre-generate the classpath:
lein deps lein classpath > cp.txt
This lets us run “raw” Clojure, without any tooling. Assuming a Bash-like shell:
time java -cp "$(cat cp.txt)" clojure.main -e '(System/exit 0)'
Now add Leiningen:
time lein run -m clojure.main -e '(System/exit 0)'
Next, add the Leiningen REPL:
time lein repl <<< "(exit)"
If you’re a fan of Emacs and CIDER, start Emacs and paste this into a scratch buffer:
(require 'cider) (defvar cider-jack-in-start-time nil) (defun start-timing-cider-jack-in (&rest args) (setq cider-jack-in-start-time (current-time))) (defun elapsed-time-cider-jack-in (&rest args) (when cider-jack-in-start-time (prog1 (format "%.3f seconds" (float-time (time-since cider-jack-in-start-time))) (setq cider-jack-in-start-time nil)))) (add-function :before (symbol-function 'cider-jack-in) #'start-timing-cider-jack-in) (setq cider-connection-message-fn #'elapsed-time-cider-jack-in)
Evaluate that Elisp code with M-x eval-buffer
, then open up your project.clj
and run cider-jack-in
.
Run each of these examples a few times to warm up the circuits.
How long does it take? On an empty project with just Clojure 1.8, I get:
java -cp … clojure.main | 0.8 seconds |
lein run -m clojure.main | 2.2 seconds |
lein repl | 4.2 seconds |
cider-jack-in | 11.5 seconds |
Yes, Clojure start-up could be faster, but make sure you know where the time is really going.
My environment: Leiningen 2.7.1, Oracle JDK 1.8.0_92, OS X
That cleared up some misconceptions and was actually quite enlightening for me. Thank you.
I really do not care much about startup time: Its a single cost at the beginning when starting the environment.
On a Raspberry PI (my home development environment) cider-jack-in-clojurescript takes slightly less than 3 minutes (using the standard ClojureScript, nothing self-hosted for now).
As I am at home, I use the time to get a beer, the delay works as the perfect excuse.
Yes! I went to a fair amount of work building a Clojurescript/Javascript command line “filter” because I figured the JVM couldn’t possibly start Clojure fast enough to be used as a “filter” at the command line. Then, after my wife (who works on the JVM) suggested ways to improve the Java/Clojure startup, I tried harder. Ultimately I built a Clojure uberjar which includes non-trivial code that will start up and run in the JVM in under 1 second on a reasonable machine. Building the uberjar requires AOT-ing the code, and installing it requires some Java magic that takes a script the first time you use it. But after that, it runs as a unix “filter” and will start up and run in less than one second. Anyone could do this. See https://github.com/kkinnear/zprint/blob/master/doc/filter.md for the full story (including comparative performance measurements) — including how you could do this yourself.