Nick
Nick

Reputation: 9051

Is the performance the same with lein run and java -jar myapp?

I'm learning the clojure luminus web framework. In the tutorial, I can run my app simply with lein run in the project directory. And of course, I could compile the project with lein uberjar, and run it with java -jar myapp.jar. I've found that the java -jar myapp.jar approach slightly faster during load test.

Question:

  1. Is clojure code compiled when it is run in the REPL?

  2. Why run the jar file faster than the lein run approach? (Please correct me if I was wrong.)

  3. Is it possible to open a REPL when running the compiled jar file?

Upvotes: 4

Views: 443

Answers (3)

Arthur Ulfeldt
Arthur Ulfeldt

Reputation: 91554

  1. Yes Clojure code is always compiled there is exactly one execution mechanism for Clojure. The compiler runs everytime you hit enter from the repl at the end of a top level form. Nothing is ever interpreted. In addition to this It's useful to keep in mind that benchmarking this stuff is hard and needs to be done carefully.
  2. there literally no difference between invoking a function through the REPL and not through the REPL. The only difference between loading a namespace through a REPL and loading it from a jar is that the last form in the file is sent back to n-repl and a status message is sent back to n-repl. putting your code in a jar does not change the compilation process it is still compiled at load time. If you AOT your code explicitly then the startup time will be shorter, and after that the run time speed will be identical. Once again, benchmarking these things is hard. In addition to making all else the same make sure you are using the same logging in both cases.
  3. yes, I do this on just about every project. just run:
    (nrepl/start-server :port port :bind "127.0.0.1")
    This requires you to use ssh port forwarding to get to the socket, which is a good security practice. Don't leave your nrepl ports hanging out there.

Upvotes: 2

Piotrek Bzdyl
Piotrek Bzdyl

Reputation: 13175

There are at least two major factors:

JVM parameters

JVM parameters might be different and they are controller either by lein config when you use lein run or directly by you if you run it manually via java .... Parameters like HotSpot compiler options, memory and GC configuration. You can use tools like jstat, jinfo and jconsole to check the effective JVM settings.

Application configuration

Check your lein profiles and which is run in either case. You might run your application in two different app configuration changing things like ring's hot code reloading, different set of ring middlewares (check files in env directory of your project) etc.

Upvotes: 0

Sergey Tselovalnikov
Sergey Tselovalnikov

Reputation: 6036

There are many reasons why this is happening can exists. The most obvious is a TiredCompilation option which is used by lein. It changes JIT behavior, so it can affect benchmark results significantly.

You can disable changing JVM options by lein:

:jvm-opts ^:replace []

Or

$ export LEIN_JVM_OPTS=

See lein wiki.

Upvotes: 1

Related Questions