更新
根据许多人的建议,看起来这是因为clojure代码首先被编译,然后再执行。AOT编译应该有所帮助。鉴于我发现实际的Clojure AOT编译过程有点棘手(例如classpath问题、目录问题等等),我在这里写了一个小的逐步过程,以供有兴趣的人参考。
大家好,
我正在阅读《Programming Clojure》并比较我用于一些简单代码的一些语言。我注意到在每种情况下,clojure实现都是最慢的。例如,
Python - hello.py
def hello_world(name):
print "Hello, %s" % name
hello_world("world")
结果如下,
$ time python hello.py
Hello, world
real 0m0.027s
user 0m0.013s
sys 0m0.014s
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");
}
}
以及结果,
$ time java hello
Hello, world
real 0m0.324s
user 0m0.296s
sys 0m0.065s
最后,
Clojure - hellofun.clj
(defn hello-world [username]
(println (format "Hello, %s" username)))
(hello-world "world")
以及结果,
$ time clj hellofun.clj
Hello, world
real 0m1.418s
user 0m1.649s
sys 0m0.154s
这是整整1.4秒的时间!有没有人知道造成这个问题的原因?Clojure真的那么慢吗,还是需要使用JVM技巧等来加快执行速度?
更重要的是,这种巨大的性能差异在某些时候不会成为一个问题吗?(我的意思是,假设我在生产系统中使用Clojure - 我得到的利益似乎完全被我在这里看到的性能问题所抵消了)。
这里使用的机器是一台2007年的Macbook Pro,运行Snow Leopard系统,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