On Tuesday, 9 July 2013 17:31:21 UTC+1, puzzler wrote:

> On Tue, Jul 9, 2013 at 8:11 AM, Alexander Gunnarson <
> alexander...@gmail.com <javascript:>> wrote:
>
>> My idea, which is probably very naive, but one which I'm curious about, 
>> is:
>>
>> *Is it possible to have some sort of set of automatic-optimizing macros that 
>> work on Clojure code to preserve elegance while maximizing performance?*
>>
>> *
>> *
>>
>> In theory, it would be kind of an abstraction layer. There would be one file 
>> that would store the code that gets read and another output file that stores 
>> the code that actually gets evaluated by the REPL, and a set of macros to 
>> optimize the "front-end", "abstracted" file into the output, 
>> "nuts-and-bolts" file to be evaluated by the REPL. Probably this would be a 
>> very intensive process - I don't know. But maybe it's worth the trouble 
>> after all to save a ton of programmer-hours by increasing readability.
>>
>>
>>
> I think you're probably underestimating the scope of what the Clojure 
> compiler already does.  Arguably, it already is an auto-optimizing process 
> that works on Clojure code to preserve elegance while maximing performance.
>

The Clojure Compiler is fine, but it doesn't really do much in the way of 
optimisation yet. 

It mainly just emits bog-standard bytecode corresponding to the 
(macro-expanded) Clojure source. The good news is that the JVM JIT is 
exceptionally good at micro-optimisation and this still results in pretty 
decent performance. The bad news is that we are missing a lot of 
opportunities to do optimisations that the JVM JIT can't possibly do 
(because it doesn't know anything about the higher level structure and 
assumptions in the code).

I think we should aspire to improve the compiler further: we should 
encourage ideas and discussions about how to improve it. 

I'd personally love to see Clojure match Java/Scala in performance for 
idiomatic code, but we are still currently some way off.
 

>
> For the most part, Clojure programmers seem to be satisfied with dropping 
> down to Java when the Clojure code gets too low-level to be elegant 
> (although I think many would disagree that your examples have reached the 
> level of inelegance).  Still, there's probably room for something that 
> targets the performance gap between Clojure and Java.
>
> I'm interested in an assembly-like DSL that could be easily interwoven 
> with Clojure code, something like:
> http://www.rebol.com/docs/rebcode.html
>
> Zach Tellman recently released a library that does something like that:
> https://github.com/ztellman/primitive-math 
>
> So far, the vast majority of Clojure performance improvements have focused 
> on making it easier to work with primitive numbers (in loops and as 
> function inputs), because Java's boxed numerics is what usually kills 
> performance.  I've only found these improvements marginally useful because 
> I find that most numbers eventually end up in a Clojure data structure, 
> where they become boxed.
>

That's one of the reasons why we are building core.matrix :-)
 

>
> For me, the most useful thing would be an ability to drop down and do fast 
> pointer manipulation and other mutable work, without having to go all the 
> way to Java.
>

Yeah, I've always wanted this too. Especially for mutable local counters / 
accumulators. I'd love to be able to do something like:

(let [^:mutable a 0 , ^:mutable b 0]
  (dotimes [i 1000] 
    (set! a (+ a (foo i)))
    (set! b (+ b (bar i))))
  ... more stuff with a and b....)

This should compile down to something that performs the same as the 
equivalent loop in Java.

Of course, it would be even better if the following could compile down to 
the same optimised loop:

(reduce (fn [[a b] i] [(+ a (foo i)) (+ b (bar i))]) [0 0] (range 1000))

But currently..... the Clojure reduce version is around 20-50x slower vs. 
equivalent Java code.
 

>
> Going in the other direction, I'd be interested in mechanisms that made it 
> easier to write recursive code without having to worry about stack 
> overflow. 
>
>
A reasonably simple optimisation would be to automatically identify 
self-recursion in tail position and convert it directly to "recur". I think 
that's possibly the kind of optimisation pass that the OP was suggesting. 

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to