Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You can write fast or slow code in any language :-)</p> <p>Based on a quick inspection of some of the Clojure code, I would say that the main reason for the performance difference is that the Clojure benchmark code hasn't yet been fully optimised to use the fastest language features available.</p> <p>For example the following features in Clojure are all very cool and useful for development convenience, but incur some runtime performance overhead:</p> <ul> <li>Lazy sequences and lists</li> <li>Dynamic Java interoperability using reflection</li> <li>Runtime function composition / first class functions</li> <li>Multimethods / dynamic dispatch</li> <li>Dynamic compilation with eval or on the REPL</li> <li>BigInteger arithmetic</li> </ul> <p>If you want absolute maximum performance (at the cost of some extra complexity), you would want to rewrite code to avoid these and use things like:</p> <ul> <li>Static type hinting (to avoid reflection)</li> <li>Transients</li> <li>Macros (for compile time code manipulation)</li> <li>Protocols</li> <li>Java primitives and arrays</li> <li>loop / recur for iteration</li> </ul> <p>With judicious use of the above, I have found that it is generally possible to get very close to Java performance in Clojure 1.2+, e.g. consider the following code to do one million additions:</p> <p><strong>Unoptimised Clojure</strong> using a lazy sequence and biginterger arithmetic. It's nice and functional but it's not particularly fast:</p> <pre><code>(reduce (fn [acc val] (unchecked-int (unchecked-add (int acc) (int val)))) (range 0 1000000)) =&gt; "Elapsed time: 65.201243 msecs" </code></pre> <p><strong>Optimized Clojure</strong> with primitive arithmetic and loop / recur:</p> <pre><code>(loop [acc (int 0) i (int 0)] (if (&gt;= i (int 1000000)) acc (recur (unchecked-add acc i) (unchecked-inc i)) )) =&gt; "Elapsed time: 0.691474 msecs" </code></pre> <p><strong>Java</strong> code, a pretty standard iterative loop:</p> <pre><code>public static int addMillion() { int result=0; for (int i=0; i&lt;1000000; i++) { result+=i; } return result; } =&gt; "Elapsed time: 0.692081 msecs" </code></pre> <p>p.s. I have used unchecked-add rather than + in the Clojure code so that it matches the integer overflow behaviour of Java.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload