>From my experience, you can get 1/1.2 performance (20% slower) with Clojure 
by following these steps:

* Choose right clojure idioms

That means to never use lazy seqs if you care for java-like performance. 
For fast looping, use reducers, for fast inserts, use transients. 
Postpone the data creation until the last step. Compose functions instead 
of piping collections containing intermediate results.
Know the tradeoffs between similar functions (e.g. rseq and reverse)
Use custom datatype with ^:unsynchronized-mutable for performance critical 
mutations, instead of atoms or vars.

* Use domain knowledge for your advantage 

Collection has a random access? Use it to your advantage. 
Is it backed by array? Do a bulk copy instead of one element per iteration.
Is memory killing you? Use subcollections which share underlying data with 
original ones.
If shooting for performance, you do not want the most generic solution. 
Search for more performant solutions which have trade-offs you can live 
with.
Do not use polymorphic dispatch if you have a closed set of options. If you 
do, prefer protocols to multimethods.

* Trade between memory and CPU (and precision)

Have a CPU intensive pure function? Memoize.
Using too much memory? Use lazy seqs, delays, dropping caches.
(Do not care for precision? Round, truncate and approximate. Use decayed 
collections, frugal streaming, ...)

* Paralellize

Clojure's approach to the concurrency allows you to focus on the problem 
and not fight much with the synchronization details. 
Using and customizing fold idiom is a good start.
(What would be a good addition to the clojure is a simple abstraction on 
top of executors and forkjoin pool for even more fine tuning.)

* Know your host

Use type hints to get rid of reflection and boxing. Most of time you can 
eliminate all reflections, but it is very hard to eliminate every automatic 
boxing/unboxing without dropping down to java.
Heavy IO use? Build your abstractions around java.nio.Buffer.
Looping with ints is faster than with longs.


While any part of your code should be idiomatic and with good design 
behind, use heavy optimization 'tricks' only to those parts of the code 
which bring the most effect. Your time can be spent on more useful things 
than optimizing some auxilliary functionality.

Best,
Jozef


On Saturday, March 1, 2014 6:02:26 AM UTC+1, bob wrote:
>
> Hi,
>
> Can I ask a newbie question about clojure performance?
>
> What make clojure performance slow than java?, it seems clojure has the 
> 1/4 performance compared to java in general, according to  tests, some 
> cases it might be 1/10. the reasons I can think out are 
>
> - the byte code is not efficient sometimes
> - the byte code might not enjoy the jvm optimization
> - the reflection 
> - the immutable data structure
> - the abstract interface design
>
> The abstract interface like seq offers its power, but it is easy to drop 
> in the performance trap.
>
> And it seems to me that it is easy to write a slow clojure program, I know 
> the efficiency of code depends on coder, you can write the code faster than 
> java sometimes,but  need to know a lot of deep thing and tricky, and 
> clojure is not the funny clojure any more.
>
>
> Thanks
>
>

-- 
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