Live data from Hacker News

Why is Clojure so slow?

martinsprogrammingblog.blogspot.de

81–90 of 97 posts

Re: Why is Clojure so slow?

#81
post #78

Earlier quoted context omitted.

No it doesn't. Development time is a one off (for a given feature set). Usage is recurring, so savings in running time catch up and eventually dwarf development time. But I don't think this calculation makes much sense in the first place. It's simply not that linear and depends on many other things, for instance whether it's a throughput or response time problem, the relative value being the first to market versus be…

> Development time is a one off (for a given feature set) Indeed. With a feature set dynamic enough, the lead will mount up.

Or the lead may just shrink more slowly.

Re: Why is Clojure so slow?

#82
post #28

Earlier quoted context omitted.

Vars already default static, so we just need to take better advantage of that in the compiler.

Yes, Clojure 1.4 defaults to static. However, a Var still needs to do an extra lookup at runtime. A Var does not directly point to the object that I want. And Vars have to be that way, this is their core feature. Clojure is a dynamic language, so they need to stay dynamic too. All code constantly assumes that the objects behind Vars will change. Let’s say we have `(defn foo [] 1)`. The caller of (foo) will first look…

user=> (defmacro value [& body] (let [retval# (eval `(do ~@body))] retval#))

#'user/value

user=> (macroexpand '(value (+ 1 3)))

4

Re: Why is Clojure so slow?

#83
post #79
post #77

Earlier quoted context omitted.

>>"Otherwise, it measures JVM startup time, and then it measures how long it takes the JIT to achieve maximum optimization." Please take that Clojure mandelbrot program, make repeated timing measurements without restarting the JVM and then report how those times compare to cold start on your computer. The mean "warmed" times for the Java mandelbrot program were actually slower than the reported cold start time for th…

Sure thing. I made it run for 4000 cycles twice. The first (cold) run took 2831.323 ms, and the warmed-up run took 2571.397 ms. About 10% faster. Judging by the invocation noted at the bottom of http://shootout.alioth.debian.org/u64/program.php?test=mande... , the comments about Java in the FAQ do not apply to the Clojure code. The benchmark seems to have been invoked straight from the command line.

Cool! Now let's check the basics:

- 2831.323 ms for what workload? The benchmarks game measurements are made at 3 different workloads; but the times that matter are those for the largest workload, in this case N=16,000. So please show the times for N=16,000.

- the benchmarks game measurements are made with output redirected to /dev/null

- both the clojure and java programs are invoked straight from the command line, and include start-up. The Help page provides additional "warmed" measurements for the fastest Java programs, for comparison - because sometimes the JVM startup costs are larger in the mind than they are when measured :-)

Re: Why is Clojure so slow?

#84
post #37
post #6

Earlier quoted context omitted.

> If Clojure could dump the Lisp image like SBCL's save-lisp-and-die function, the startup time would be greatly reduced. I wonder if JVM itself can dump its current state and then restore execution. It's still hard to understand why aren't Oracle working on something like that. It's not as if they don't care about desktop at all -- JavaFX is going to be part of Java8 and they are even working on a new packaging tool…

"JVM's start-up time and inability to allocate memory when needed (as compared to up-front way it's done now).." Care to elaborate? Are you saying that the JVM can't malloc()? :)

As far as mine understanding of JVM goes it works with memory in quite a different way. When JVM starts up it allocates large chunk of memory up-front (usually hundreds of megabytes) even though it doesn't really need all that memory. Usually only a part of that memory is actually used at any given moment. JVM will manage that memory with custom internal malloc/free which will allocate memory to Java objects. All this is needed to implement efficient garbage collection. See [1] for details.

Such complicated memory management is really efficient and works great for server apps. On the client -- not so much. In that case I would rather prefer a slower GC that just uses malloc/free. Why? Because from end-user perspective that's not really great when a simple app grabs a 100-200mb of memory. If all apps were like this you wouldn't be able to run many of them at the same time. (Especially on the older hardware.) Moreover for a complex JVM apps 500mb+ of allocated RAM might be a requirement. [2]

Great example of how things should work is .NET/Mono. Both of the .NET runtimes allocate memory only when it's actually needed and start-up performance is great too. All things considered JVM and CLR are very similar runtimes and there is no reason for a more client-oriented JVM implementation not to be possible.

[1] http://www.quora.com/How-does-garbage-collection-work-in-the...

[2] Eclipse for instance recommends to configure jvm to allocate at least 500mb up-front. (This is done via -Xms and -Xmx parameters.)

Re: Why is Clojure so slow?

#85
post #80
post #72

Earlier quoted context omitted.

>>Note that the "alternative" ... A program that simply switched according the command line arg and then printed: 3968050 Pfannkuchen(12) = 65 :would also out perform :-) >>I imagine a more clever Ruby programmer could reduce that... Is "a more clever Ruby programmer" some kind of equivalent to "a sufficiently smart compiler"? :-) >>or just call out to a native library When is a Ruby program fast? When it's written i…

> A program that simply switched according the command line arg and then printed… Of course making programs do less can improve speed, and a great way of doing that is compile-time computation via macros! You can finish the program before it's even run. > Is "a more clever Ruby programmer" some kind of equivalent to "a sufficiently smart compiler"? No, since we assume human intelligence here. :P As the Graphics Progr…

I've spent enough time asking for programs for the benchmarks game in Ruby forums, to start to doubt whether the "more clever Ruby programmer" will ever come forward ;-)

Maybe "a more clever Ruby programmer" always drops-down to C?

Maybe there's only a more clever Rails programmer :-)

Re: Why is Clojure so slow?

#86
post #64

Earlier quoted context omitted.

Those benchmarks are fairly useless, because it doesn't compare idiomatic usage of those languages, but rather the capability of those languages to drop to low-level primitives and libraries. I did an experiment once, testing out a simple web-service on the JVM and Scala (with Scalatra) yields the same performance as Java (with Jax-RS), while Clojure (with Noir) is only 2x to 3x as slow and JRuby (Sinatra) is only 4x…

>>Those benchmarks are fairly useless, because it doesn't compare idiomatic usage of those languages... You seem to be complaining that the programmers were not forced to write slow programs :-) >>I did an experiment once... And you used libraries.

No, I'm complaining that those benchmarks aren't mirroring the way developers actually write code.

Re: Why is Clojure so slow?

#87
post #83
post #79

Earlier quoted context omitted.

Sure thing. I made it run for 4000 cycles twice. The first (cold) run took 2831.323 ms, and the warmed-up run took 2571.397 ms. About 10% faster. Judging by the invocation noted at the bottom of http://shootout.alioth.debian.org/u64/program.php?test=mande... , the comments about Java in the FAQ do not apply to the Clojure code. The benchmark seems to have been invoked straight from the command line.

Cool! Now let's check the basics: - 2831.323 ms for what workload? The benchmarks game measurements are made at 3 different workloads; but the times that matter are those for the largest workload, in this case N=16,000. So please show the times for N=16,000. - the benchmarks game measurements are made with output redirected to /dev/null - both the clojure and java programs are invoked straight from the command line,…

Well certainly, in a real-world program which runs for long periods analyzing tons of data, JVM startup costs and JIT costs amount to nothing, as they are paid in the first few seconds. But we are talking about short, synthetic benchmarks here.

I ran mandelbrot for 4000 cycles, just invoking the function which does the work twice and wrapping each call in Clojure's (time ...) form. This all happened in an AOT-compiled .class file, which guaranteed a cold start. For what it's worth, I didn't bother tuning the GC or any other JVM parameters — I suspect I could have made it run a bit faster by manipulating generation sizes.

Re: Why is Clojure so slow?

#88
post #87
post #83

Earlier quoted context omitted.

Cool! Now let's check the basics: - 2831.323 ms for what workload? The benchmarks game measurements are made at 3 different workloads; but the times that matter are those for the largest workload, in this case N=16,000. So please show the times for N=16,000. - the benchmarks game measurements are made with output redirected to /dev/null - both the clojure and java programs are invoked straight from the command line,…

Well certainly, in a real-world program which runs for long periods analyzing tons of data, JVM startup costs and JIT costs amount to nothing, as they are paid in the first few seconds. But we are talking about short, synthetic benchmarks here. I ran mandelbrot for 4000 cycles, just invoking the function which does the work twice and wrapping each call in Clojure's (time ...) form. This all happened in an AOT-compile…

>>I ran mandelbrot for 4000 cyclesThat reduced workload only runs the program for 1/10th the time of the workload shown on the benchmarks game website.

Run the program for N=16,000 and see that "JVM startup costs and JIT costs amount to nothing" even for these "short, synthetic benchmarks".

(Incidentally, the "usual" cold start measurement shown on the website is the best of 6.)

Re: Why is Clojure so slow?

#89
post #64

Earlier quoted context omitted.

>>Those benchmarks are fairly useless, because it doesn't compare idiomatic usage of those languages... You seem to be complaining that the programmers were not forced to write slow programs :-) >>I did an experiment once... And you used libraries.

No, I'm complaining that those benchmarks aren't mirroring the way developers actually write code.

What specifically do you think the difference is, and how do you know?

Re: Why is Clojure so slow?

#90
post #64

Earlier quoted context omitted.

>>Those benchmarks are fairly useless, because it doesn't compare idiomatic usage of those languages... You seem to be complaining that the programmers were not forced to write slow programs :-) >>I did an experiment once... And you used libraries.

No, I'm complaining that those benchmarks aren't mirroring the way developers actually write code.

[deleted]
Post reply on HN