与Java和Python相比,为什么Clojure Hello World程序如此之慢?

vik*_*sit 11 comparison performance jvm functional-programming clojure

更新

正如许多人所建议的那样,看起来这是因为clojure代码首先被编译然后执行.AOT编译应该有助于抵消这一点.鉴于我发现实际Clojure的AOT编译过程有点棘手,解决(类路径问题,目录问题等),我写了一个小循序渐进的过程在这里,如果有人有兴趣.


大家好,

我正在阅读"Programming Clojure",我正在比较一些用于简单代码的语言.我注意到clojure实现在每种情况下都是最慢的.例如,

Python - hello.py

def hello_world(name):
  print "Hello, %s" % name

hello_world("world")
Run Code Online (Sandbox Code Playgroud)

结果,

$ time python hello.py
Hello, world

real    0m0.027s
user    0m0.013s
sys 0m0.014s
Run Code Online (Sandbox Code Playgroud)

Java - hello.java

import java.io.*;

public class hello {
  public static void hello_world(String name) {
    System.out.println("Hello, " + name);
  }

  public static void main(String[] args) {
    hello_world("world");
  }
}
Run Code Online (Sandbox Code Playgroud)

结果,

$ time java hello
Hello, world

real    0m0.324s
user    0m0.296s
sys 0m0.065s
Run Code Online (Sandbox Code Playgroud)

最后,

Clojure - hellofun.clj

(defn hello-world [username]
  (println (format "Hello, %s" username)))

(hello-world "world")
Run Code Online (Sandbox Code Playgroud)

和结果,

$ time clj hellofun.clj 
Hello, world

real    0m1.418s
user    0m1.649s
sys 0m0.154s
Run Code Online (Sandbox Code Playgroud)

这是一个整体,garangutan 1.4秒!

有没有人指出这可能是什么原因?Clojure真的那么慢,还是需要使用JVM技巧等来加速执行?

更重要的是 - 在某种程度上,性能上的巨大差异不是一个问题吗?(我的意思是,假设我在生产系统中使用Clojure - 使用lisp获得的收益似乎完全被我在这里看到的性能问题所抵消).


这里使用的机器是运行Snow Leopard的2007 Macbook Pro,2.16Ghz Intel C2D和2G DDR2 SDRAM.

顺便说一句,我正在使用的clj脚本来自这里,看起来像,

#!/bin/bash
JAVA=/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/bin/java
CLJ_DIR=/opt/jars
CLOJURE=$CLJ_DIR/clojure.jar
CONTRIB=$CLJ_DIR/clojure-contrib.jar
JLINE=$CLJ_DIR/jline-0.9.94.jar
CP=$PWD:$CLOJURE:$JLINE:$CONTRIB

# Add extra jars as specified by `.clojure` file
if [ -f .clojure ]
then
  CP=$CP:`cat .clojure`
fi

if [ -z "$1" ]; then
  $JAVA -server -cp $CP \
      jline.ConsoleRunner clojure.lang.Repl
else
  scriptname=$1
  $JAVA -server -cp $CP clojure.main $scriptname -- $*
fi
Run Code Online (Sandbox Code Playgroud)

dno*_*len 27

除了Clojure启动时间,你在这里测量的不多.您也正在以一种测量编译时间的方式运行程序.如果您希望看到更快的加载时间,则需要提前编译代码.

在Python中编写了一些代码之后,我发现Clojure作为一般规则比Python更快,更快,你通常可以得到一个Clojure程序,以获得纯Java速度的2X-4X.

  • 如果您将可变列表与向量进行比较,您将看到一个性能差异.在Clojure中,当perf真正重要时,我会使用Java数组,或者对它们进行轻量级抽象.也就是说,PyPy的表现看起来非常好.然而,既然我已经熟悉/熟悉从Clojure中获取性能,我认为在PyPy与JVM竞争之前还有一些方法可以解决. (2认同)