Обновление
Как предложили многие люди, похоже, что это было из-за того, что код clojure был сначала скомпилирован и затем выполнен. Компиляция AOT должна помочь сместить это. Учитывая я нашел практический процесс компиляции Clojure AOT немного хитрым для решения (проблемы пути к классу, проблемы каталога и др.), я описал небольшой шаг процессом шага здесь, в случае, если любому интересно.
Привет все,
Я читаю "Программирование 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
Это - целое, секунды garangutan 1.4!
У кого-либо есть указатели на том, какова причина этого могла быть? Clojure действительно, что медленный, или там приемы JVM и др., которые должны использоваться для ускорения выполнения?
Что еще более важно - не эта огромная разница в производительности, собирающейся быть проблемой в какой-то момент? (Я имею в виду, позволяет, говорят, что я использовал Clojure для производственной системы - усиление, я вхожу в использование шепелявости, кажется полностью смещенным проблемами производительности I, видят здесь).
Машиной, используемой здесь, является MacBook Pro 2007 рабочий Snow Leopard, Intel C2D на 2.16 ГГц и 2G DDR2 SDRAM.
BTW, 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
Вы здесь мало что измеряете, за исключением времени загрузки Clojure. Вы также запускаете свою программу таким образом, что вы также измеряете время компиляции. Если вы хотите, чтобы время загрузки было быстрее, вам нужно заранее скомпилировать код.
Немного написав код на Python, я обнаружил, что Clojure, как правило, намного, намного, намного быстрее, чем Python, и вы обычно можете получить программу Clojure, которая будет в 2-4 раза быстрее чистой Java.
Также обратите внимание, что параметр '-server' в вашем скрипте clj будет использовать 'серверную JVM', которая оптимизирована для длительных процессов за счет более медленного запуска.
Ваш пример java не включает эту опцию, поэтому он, вероятно, использует «клиентскую JVM», которая оптимизирована для более быстрого запуска.
Попробуйте запустить java -jar clojure.jar -i hellofun.clj для более справедливого сравнения.
Чтобы добавить к ответу dnolen'а, при выполнении временного содержимого на Python и Clojure, вы можете упаковать вашу "основную единицу работы" как функцию, а затем использовать макрос time
(в Clojure) или функцию timeit.timeit
(в Python; или, что еще лучше, использовать средства синхронизации IPython) в REPL. Результаты должны быть примерно сопоставимы. (Обратите внимание, что код Clojure нужно "разогреть", запустив его несколько раз, чтобы достичь полной производительности)
Есть также несколько наборов бенчмарков для Clojure, например Criterium; вы можете рассмотреть возможность использования одного из них.