The unoptimized code:
(set! *warn-on-reflection* true) (def filename (first *command-line-args*)) (use '[clojure.java.io :only [input-stream]]) (def stream (input-stream filename)) (defn slowjure [n] (def b (.read stream)) (cond (== b -1) n :else (recur (bit-xor n b)))) (println "Clojure XOR of bytes: " (slowjure 0))The optimized code:
(set! *warn-on-reflection* true) (def filename (first *command-line-args*)) (use '[clojure.java.io :only [input-stream]]) (def stream (input-stream filename)) (defn slowjure [n] (def b (.read ^java.io.BufferedInputStream stream)) (cond (== b -1) n :else (recur (bit-xor n b)))) (println "Clojure XOR of bytes: " (slowjure 0))
Adding this type annotation for ^java.io.BufferedInputStream allowed Clojure to avoid doing reflection and gave me more than a 60% performance boost!
Of course this makes me mad: how was I supposed to know this? I'm pretty sure learning Clojure will teach me more about Java's type system than a language that explicitly avoids using those types should!
Is this faster on Clojure 1.3? Can you speed it up some other way? This version was still so slow I'm leaving it out of a comparison with some other languages...
0 comments:
Post a Comment