Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is any Java/Clojure program slowed down when run from Leiningen?

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.

like image 676
pron Avatar asked Apr 18 '13 10:04

pron


2 Answers

The creators of leiningen are aware of this and give a thorough explanation of why this is so and what you can do about this.

https://github.com/technomancy/leiningen/wiki/Faster

Related question: Why is leiningen so slow when it starts?

like image 58
tixel Avatar answered Nov 15 '22 17:11

tixel


It's probably due to different JIT behaviour.

The performance of JIT compiled can be affected by a number of things, including:

  • What startup code gets called, which will affect JIT statistics
  • What other classes have been loaded (e.g. other subclasses of Random) which could affect the compiler's optimisation of method call dispatch
like image 34
mikera Avatar answered Nov 15 '22 17:11

mikera