While benchmarking a Clojure app and trying to pin down performance problems, I noticed this peculiar behavior: even when the entire program is written in Java, when launched from Leiningen it seems to experience a significant slowdown.
Say I have this Java program:
public class Foo {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++)
run();
}
public static void run() {
final long start = System.nanoTime();
Random r = new Random();
double x = 0;
for(int i=0; i<50000000; i++)
x += r.nextDouble();
final long time = TimeUnit.MILLISECONDS.convert(System.nanoTime() - start, TimeUnit.NANOSECONDS);
System.out.println("time (ms): " + time + " total: " + x);
}
}
When I simply run the program, I get execution times (per run
) of about 1s. However, when I run it from leiningen like so:
lein run -m Foo
I get run times of about 2s! How does Clojure/Leiningen manage to slow down a complete Java program by so much? What am I doing wrong?
I've tried examining the system properties in both runs and couldn't find anything glaring (like different JIT settings). In both cases I use Java 7 with the server compiler.
EDIT: I don't know why this question has been downvoted. I'm not against Clojure. On the contrary, I love Clojure and I'm going to use it. I just have this serious performance problem that I absolutely must solve.
UPDATE: Running lein trampoline
solves the issue! (though I have no idea why)
I've updated the question to reflect that this is indeed a Leiningen issue, not a Clojure issue.
Another update: This happens for any Clojure code as well. Running without trampoline slows down code by up to 5x.
lein help trampoline
– Polyglot