Live data from Hacker News

Clojure 1.3 First Impression (It's Fast)

learningclojure.com

11–20 of 26 posts

Re: Clojure 1.3 First Impression (It's Fast)

#11

As someone familiar with Java/Scala but not Clojure, what exactly do those type hints do? Just prevent it from autoboxing the primitives? Avoid excessive reflection? Can this be done for other types or just int/long/float/etc?

The diffrence form Java/Scala is that Clojure dosn't type check (like say typed scheme). Is just for performance.

typhinting to avoid reflection can be done for all java objects. The autoboxing is only for numeric stuff.

Re: Clojure 1.3 First Impression (It's Fast)

#12

As someone familiar with Java/Scala but not Clojure, what exactly do those type hints do? Just prevent it from autoboxing the primitives? Avoid excessive reflection? Can this be done for other types or just int/long/float/etc?

type-hinting Java objects to avoid reflection has been possible for some time now. What wasn't possible was for fns to take or return primitives w/o boxing. ^:static lets you do that. ^:static also allows the JVM to apply the most aggressive optimizations to your code - ^:static tells the JVM the code won't change - so callers of ^:static fns won't get the latest version if you redef them. The benefit being that with…

CMUCL, dealing with a similar infinitely-dynamic problem in Lisp, had a similar approach but dealt with it on a block-of-code level instead of per-function. You could declare a block to be compiled together, and any calls between functions in the block would be treated as having a promise that you'd never redef them without recompiling the whole block, so they could be statically optimized with respect to each other.

Not sure if that's a better or worse approach overall. It probably depends on the structure of your program. One nice feature was that the same function could be static from some perspectives and not from others--- to functions in the same compilation block it was static, but functions from outside that block that called it treated it as non-static, and would immediately get the new version if, say, that whole block were recompiled. That let you make the core code optimized by sticking it in one big compilation block, while not changing the normal dynamic Lisp semantics of the block when viewed from the perspective of any outside function.

Re: Clojure 1.3 First Impression (It's Fast)

#13
post #5

Earlier quoted context omitted.

Scala effectively has these kinds of type declarations on every function. This article itself proves the point. Take out the :static and type decls and see.

Idiomatic Clojure tends to use Clojure's persistent data structures - you don't often create custom types, all of the core functions on those data structures are already pretty much as fast as possible. No need for ^:static or type decls. The article also doesn't get into deftype/defrecord/protocols. In those cases you always get the fastest path of the platform. Again you can build things that have the same perf of…

It's strange that you mention Clojure's persistent data structures as an advantage for performance. They have many advantages but performance isn't one of them.

Re: Clojure 1.3 First Impression (It's Fast)

#14

Earlier quoted context omitted.

type-hinting Java objects to avoid reflection has been possible for some time now. What wasn't possible was for fns to take or return primitives w/o boxing. ^:static lets you do that. ^:static also allows the JVM to apply the most aggressive optimizations to your code - ^:static tells the JVM the code won't change - so callers of ^:static fns won't get the latest version if you redef them. The benefit being that with…

CMUCL, dealing with a similar infinitely-dynamic problem in Lisp, had a similar approach but dealt with it on a block-of-code level instead of per-function. You could declare a block to be compiled together, and any calls between functions in the block would be treated as having a promise that you'd never redef them without recompiling the whole block, so they could be statically optimized with respect to each other.…

Clojure supports the static from some perspectives and not from others pattern, you just have to go through the var. So even if an fn foo is declared ^:static, you can call #'foo instead so that you always get the latest version of the fn.

Re: Clojure 1.3 First Impression (It's Fast)

#15
post #13

Earlier quoted context omitted.

Idiomatic Clojure tends to use Clojure's persistent data structures - you don't often create custom types, all of the core functions on those data structures are already pretty much as fast as possible. No need for ^:static or type decls. The article also doesn't get into deftype/defrecord/protocols. In those cases you always get the fastest path of the platform. Again you can build things that have the same perf of…

It's strange that you mention Clojure's persistent data structures as an advantage for performance. They have many advantages but performance isn't one of them.

I'm curious how you come to this conclusion? Programs in any language will often be designed around immutability in order to improve code maintainability. Without fast persistent data structures this will most certainly decrease the performance of your otherwise elegant design due to considerable amounts of copying.

Re: Clojure 1.3 First Impression (It's Fast)

#16
post #13

Earlier quoted context omitted.

It's strange that you mention Clojure's persistent data structures as an advantage for performance. They have many advantages but performance isn't one of them.

I'm curious how you come to this conclusion? Programs in any language will often be designed around immutability in order to improve code maintainability. Without fast persistent data structures this will most certainly decrease the performance of your otherwise elegant design due to considerable amounts of copying.

If you're going for raw speed you should use mutable data structures. Sadly, that's just the way it is - you can update a mutable data structure in a couple of instructions by swapping out a pointer, while "updating" an immutable/persistent object is inherently more work at the machine level.

Clojure is awesome because it provides immutable persistent structures that are well onto the good side of "good enough", not because it's the fastest thing possible. Java itself is far from the fastest thing possible, and the speed of Java is itself a strict upper bound on Clojure's speed.

Re: Clojure 1.3 First Impression (It's Fast)

#17
post #13

Earlier quoted context omitted.

It's strange that you mention Clojure's persistent data structures as an advantage for performance. They have many advantages but performance isn't one of them.

I'm curious how you come to this conclusion? Programs in any language will often be designed around immutability in order to improve code maintainability. Without fast persistent data structures this will most certainly decrease the performance of your otherwise elegant design due to considerable amounts of copying.

It's threads like this that make the Clojure community really irk me sometimes. It's ok to think your language is great, but please take a reality check before you go off and try to defend it against criticism! Judging by your comments, especially this fuzzy little one about elegant design, I would guess that you've spent very little time dealing with actual CPU and memory-related performance issues.

Re: Clojure 1.3 First Impression (It's Fast)

#19
post #17

Earlier quoted context omitted.

I'm curious how you come to this conclusion? Programs in any language will often be designed around immutability in order to improve code maintainability. Without fast persistent data structures this will most certainly decrease the performance of your otherwise elegant design due to considerable amounts of copying.

It's threads like this that make the Clojure community really irk me sometimes. It's ok to think your language is great, but please take a reality check before you go off and try to defend it against criticism! Judging by your comments, especially this fuzzy little one about elegant design, I would guess that you've spent very little time dealing with actual CPU and memory-related performance issues.

It's not just me then.

Re: Clojure 1.3 First Impression (It's Fast)

#20
post #16

Earlier quoted context omitted.

I'm curious how you come to this conclusion? Programs in any language will often be designed around immutability in order to improve code maintainability. Without fast persistent data structures this will most certainly decrease the performance of your otherwise elegant design due to considerable amounts of copying.

If you're going for raw speed you should use mutable data structures. Sadly, that's just the way it is - you can update a mutable data structure in a couple of instructions by swapping out a pointer, while "updating" an immutable/persistent object is inherently more work at the machine level. Clojure is awesome because it provides immutable persistent structures that are well onto the good side of "good enough", not…

Sure, but of course if you want raw speed you would write assembly. Most people move up the food chain to C to get some basic level of correctness.

I think the history of production oriented PLs has revolved around balancing correctness/performance. And it's always a question of diminishing return (I've written enough C/C++/Objective-C++ to know this). Every sizeable application I've written in a lower level language eventually approaches some kind of wacky manual memory management scheme to preserve performance w/o sacrificing correctness. I think Clojure's solution is a step in the right direction.

But no, if I was writing a real-time system with extremely limited memory constraints I would not write in the Clojure. But I don't think that's what this thread is about.

Post reply on HN