Why is the Clojure Hello World program so slow compared to Java and Python?

后端 未结 4 1171
借酒劲吻你
借酒劲吻你 2021-02-20 08:49

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 s

相关标签:
4条回答
  • 2021-02-20 08:58

    The JVM in general already has a somewhat slow startup time as opposed to native or interpreted languages. On top of that, Clojure adds a considerable overhead to startup time, as it compiles and loads quite a bit of code on startup. Even with AOT, there's a lot of things Clojure needs to setup before it can run.

    Bottom line, don't depend on Clojure for short lived processes. Don't even rely on Java for those use cases most of the time. Something native or interpreted like Node.js, Python, Lua, etc. would be much better.

    For medium to long lived processes though, Clojure will on average be much faster then almost all other dynamic languages, beating out Python and Ruby. Clojure can be made almost as fast as Java if needed without a lot of effort, and its Java inter-op is so easy, that by changing a few functions to pure java you can in most cases get speed equal to Java.

    Now, if you really wanted something quick for Clojure, I'd recommend looking into lumo. Its a ClojureScript REPL that's self contained and running on bootstrapped ClojureScript, so no JVM to be seen.

    time python -c "print(\"Hello World\")"
    Hello World
    
    real    0m0.266s
    user    0m0.015s
    sys     0m0.202s
    
    time lumo -e "\"Hello World\""
    "Hello World"
    
    real    0m0.438s
    user    0m0.000s
    sys     0m0.203s
    

    As you can see, Lumo gets pretty close to the startup speed of Cpy3k.

    An alternative, which isn't really going to be Clojure anymore, but it will still be a Clojure inspired Lisp, is Hy. Its a Lisp with Clojure syntax running on Python.

    time hy -c "(print \"Hello World\")"
    Hello World
    
    real    0m0.902s
    user    0m0.000s
    sys     0m0.171s
    

    Its startup time is slightly slower then both Cpy3k and Lumo, but it gives you all of Python at your disposal with Clojure's syntax and macros.

    0 讨论(0)
  • 2021-02-20 09:06

    To add to dnolen's answer, when doing Python vs Clojure timing contents, you might want to package your "basic unit of work" as a function and then use the time macro (in Clojure) or the timeit.timeit function (in Python; or, better yet, use the timing facilities of IPython) at the REPL. The results should be roughly comparable. (Note that Clojure code needs to be "warmed up" by running it a few times to achieve full performance.)

    There are also some benchmarking suites for Clojure, for example Criterium; you might want to consider using one of them.

    0 讨论(0)
  • 2021-02-20 09:15

    Also, note that the '-server' option in your clj script will use the 'server JVM' which is optimized for long-running processes at the cost of slower start up time.

    Your java example didn't include this option, so it is probably using the 'client JVM', which is optimised for faster startup time.

    Try running java -jar clojure.jar -i hellofun.clj for a fairer comparison.

    0 讨论(0)
  • 2021-02-20 09:16

    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.

    0 讨论(0)
提交回复
热议问题