Tricks to make Clojure(startup time) faster?

let try~

{
 "dependencies": {
  "left-pad": "1.2.0"
 }
}

npm install

lumo

cljs.user=> (require '[left-pad :as lp])
nil
cljs.user=> (lp "foo" 5)
"  foo"

seems nice!

2 Likes

Good~

=>> lumo
Lumo 1.7.0
ClojureScript 1.9.908
Node.js v8.4.0
 Docs: (doc function-name-here)
       (find-doc "part-of-name-here")
 Source: (source function-name-here)
 Exit: Control+D or :cljs/quit or exit

cljs.user=> (require '["md5" :as md5])
nil
cljs.user=> md5
#object[Function]

Yup, that syntax is standard Clojurescript now, it should be supported no matter which tool youā€™re using.

2 Likes

Where did that happen? Last time I saw it, it was still in debate?

seems like 1.9.854

Hereā€™s the blog post that introduced that

https://clojurescript.org/news/2017-07-12-clojurescript-is-not-an-island-integrating-node-modules

2 Likes

FWIW, I didnā€™t take this as negativity, but rather pointing out an issue (the elephant in the room). I think we should pay attention to this issue. I use Clojure for lots of things and while Iā€™m very happy with server code performance, developing could definitely use speed improvements. cider-jack-in takes so long that I often go and get coffee, and if ClojureScript compilation were faster, Iā€™d be much happier, too.

I understand there are good reasons for why it is slow, but this doesnā€™t mean we shouldnā€™t pretend it isnā€™t. Progress is being made and things are getting faster.

The startup time is especially painful for me when Iā€™m doing something like formatting code with cljfmt. Iā€™m using these Boot tasks to integrate cljfmt with Boot and running boot fmt takes over 24 seconds to run on one one-line file. Am I ā€œdoing it wrongā€? Should I be running this workflow from a REPL somehow instead?

FWIW thereā€™s a nodejs version of cljfmt on npm that starts up much faster. :slight_smile:

3 Likes

I came across that before but I guess I wrote it off because there had been an ā€œupdate dependenciesā€ PR open for six months. But thank you for the link :slightly_smiling_face:

In general, though, is ā€œfind a ClojureScript versionā€ the go-to advice for any kind of tooling where a 20-second startup time is unacceptable?

I tend to do most things using a long-lived JVM process controlled from within emacs.

I wish I had a better answer but yeah I think at this point in time thatā€™s often the most feasible approach.

2 Likes

Can you share some more details about this workflow ?

Iā€™m a bit confused.
Is this the jvm started by the build tools eg. boot repl and reloading deps or controlling another jvm process?

lein repl in a project, connect to it from emacs using cider-connect. One of things that makes this work well is having something like alembic in your main lein config so that you can pull in any deps you need without restarting.

1 Like

What I still ask myself is why ClojureScript doesnā€™t suffer from having to load, compile and init all namespaces in start-up?

If the culprit is Clojure and not the JVM, does ClojureScript bootstraps in a different way which solves exponentially the slow start-up times?

Or is it indirectly the JVMā€™s fault, in that load, compile and init are exponentially slower on the JVM then they are on V8?

One thought I had is, what if Clojure fns shared a class per namespace? Would this be doable? Would it speed up start-up and lower overall memory footprint?

1 Like

Just to be clear, is Clojure startup time allways high or just for big projects or during development? I mean, a compiled small program will take that long to startup too?

JVM Clojure programs typically take a long time to start, though by ā€œa long timeā€ we mean a few seconds. Compiled ClojureScript programs running in Node start much faster (~100ms).

And that is the reason why I chose cljs for scripting, but I wanted to know how much does it take on clojure, because if it is one second vs 100ms I can live with it.

Clojure doesnā€™t take longer than a second to start. If it takes longer than a second to run a simple script that almost always means youā€™re using some other thing thatā€™s adding significant overhead - lein, boot, etc.

1 Like

Small scripts should start in around 1 second. There are cases where Clojure starts faster then ClojureScript. And if your script does a lot of CPU work, the speedup in execution time you get from Clojure can supersede the startup overhead, meaning the total execution time could still be faster in Clojure.

Take a look at this comparison: https://github.com/kkinnear/zprint/blob/master/doc/filter.md#performance-results

This is for a command line tool, and Clojure ends up being faster.

2 Likes