Update
As suggested by many people, it looks like this was because of the fact that clojure code was first compiled and then executed. AOT compilation should help offset that. Given I found the practical Clojure AOT compilation process a little tricky to solve (classpath issues, directory issues et al), I've written up a small step by step process here, in case anyone is interested.
Hi all,
I'm reading "Programming Clojure" and I was comparing some languages I use for some simple code. I noticed that the clojure implementations were the slowest in each case. For instance,
Python - hello.py
def hello_world(name):
print "Hello, %s" % name
hello_world("world")
and result,
$ 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");
}
}
and result,
$ time java hello
Hello, world
real 0m0.324s
user 0m0.296s
sys 0m0.065s
and finally,
Clojure - hellofun.clj
(defn hello-world [username]
(println (format "Hello, %s" username)))
(hello-world "world")
and results,
$ time clj hellofun.clj
Hello, world
real 0m1.418s
user 0m1.649s
sys 0m0.154s
Thats a whole, garangutan 1.4 seconds!
Does anyone have pointers on what the cause of this could be? Is Clojure really that slow, or are there JVM tricks et al that need to be used in order to speed up execution?
More importantly - isn't this huge difference in performance going to be an issue at some point? (I mean, lets say I was using Clojure for a production system - the gain I get in using lisp seems completely offset by the performance issues I can see here).
The machine used here is a 2007 Macbook Pro running Snow Leopard, a 2.16Ghz Intel C2D and 2G DDR2 SDRAM.
BTW, the clj script I'm using is from here and looks like,
#!/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 will always be slow, because it's not cache friendly. You always have the option to use the java data structures, for the cases this kind of optimization is needed.
Clojure probably won't steal the spotlight in lists of popular languages in 2022 outside of the world of functional programming. But even though Clojure does not have the buzz of other languages, it is used by many market leaders and organisations.
Python programs are generally expected to run slower than Java programs, but they also take much less time to develop. Python programs are typically 3-5 times shorter than equivalent Java programs. This difference can be attributed to Python's built-in high-level data types and its dynamic typing.
You're not measuring much here except for Clojure boot time. You're also running your program in such a way that you are measuring compilation time as well. If you want to see faster load times you'll need to ahead-of-time compile your code.
Having coded a bit in Python, I've found that Clojure is as a general rule much, much, much faster than Python and you can usually get a Clojure program to get within 2X-4X of the speed of pure Java.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With