6

在对 Clojure 应用程序进行基准测试并试图确定性能问题时,我注意到了这种特殊行为:即使整个程序是用 Java 编写的,当从 Leiningen 启动时,它似乎也经历了显着的减速。

假设我有这个 Java 程序:

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);
    }
}

当我简单地运行程序时,我得到的执行时间(每run)大约为 1 秒。但是,当我像这样从 leiningen 运行它时:

lein run -m Foo

我的运行时间约为2 秒!Clojure/Leiningen 是如何将一个完整的 Java 程序减慢这么多的?我究竟做错了什么?

我尝试在两次运行中检查系统属性,但找不到任何明显的东西(比如不同的 JIT 设置)。在这两种情况下,我都使用 Java 7 和服务器编译器。

编辑:我不知道为什么这个问题被否决了。我不反对 Clojure。相反,我喜欢 Clojure,我将使用它。我只是有这个我绝对必须解决的严重性能问题。

更新:运行lein trampoline解决了这个问题!(虽然我不知道为什么)我已经更新了问题以反映这确实是 Leiningen 问题,而不是 Clojure 问题。

另一个更新:任何 Clojure 代码也会发生这种情况。在没有蹦床的情况下运行会使代码速度降低多达 5 倍。

4

3 回答 3

3

leiningen 的创建者意识到了这一点,并详细解释了为什么会这样,以及你可以做些什么。

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

相关问题: 为什么 leiningen 启动时这么慢?

于 2015-03-17T13:22:18.000 回答
1

这可能是由于不同的 JIT 行为。

JIT 编译的性能可能会受到许多因素的影响,包括:

  • 调用了哪些启动代码,这将影响 JIT 统计信息
  • 加载了哪些其他类(例如 Random 的其他子类)可能会影响编译器对方法调用调度的优化
于 2013-04-18T12:14:21.953 回答
-1

leiningen 大约需要一秒钟才能启动。

于 2013-04-18T10:47:00.363 回答