Mercurial > rlm
diff src/rlm/iterate.clj @ 0:78a630e650d2
initial import
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 18 Oct 2011 00:57:08 -0700 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/rlm/iterate.clj Tue Oct 18 00:57:08 2011 -0700 1.3 @@ -0,0 +1,150 @@ 1.4 +(ns rlm.iterate 1.5 + "from the clojure mailing list" 1.6 + {:author "tsuraan"} 1.7 + (:gen-class 1.8 + :name "iterate" 1.9 + :main true 1.10 + )) 1.11 + 1.12 + 1.13 +(set! *warn-on-reflection* true) 1.14 +(import java.io.FileInputStream) 1.15 + 1.16 +(def *numbytes* (* 16 1024 1024)) 1.17 + 1.18 + 1.19 +(defmacro better-areduce [a idx ret init expr] 1.20 + `(let [a# ~a 1.21 + alength# (alength a#)] 1.22 + (loop [~idx (int 0) ~ret ~init] 1.23 + (if (< ~idx alength#) 1.24 + (recur (unchecked-inc ~idx) ~expr) 1.25 + ~ret)))) 1.26 + 1.27 +(defn translated-countnl 1.28 + [#^bytes buf] 1.29 + (let [total-length (alength buf)] 1.30 + (loop [count (int 0) current-index (int 0)] 1.31 + (if (>= current-index total-length) 1.32 + count 1.33 + (let [new-count 1.34 + (if (= (aget #^bytes buf current-index) (byte 10)) 1.35 + (unchecked-inc count) 1.36 + count)] 1.37 + 1.38 + (recur new-count (unchecked-inc current-index))))))) 1.39 + 1.40 +(defn countnl-classic 1.41 + [#^bytes buf] 1.42 + (let [nl (byte 10)] 1.43 + (areduce buf idx count 0 1.44 + (if (= (aget buf idx) nl) 1.45 + (inc count) 1.46 + count)))) 1.47 + 1.48 + 1.49 +(defn countnl-lite 1.50 + "this is the absolute fastest function I could come up with. 1.51 + still 2.25 times slower that the java version." 1.52 + [#^bytes buf] 1.53 + (areduce buf idx count (int 0) 1.54 + (if (= (clojure.lang.RT/aget buf idx) 10) 1.55 + (unchecked-add count 1) 1.56 + count))) 1.57 + 1.58 + 1.59 +(defn #^Boolean is-ten? [#^Integer A] 1.60 + (= A 10)) 1.61 + 1.62 +(defn countnl-max-power 1.63 + [#^bytes buf] 1.64 + (areduce buf idx count (int 0) 1.65 + (if (is-ten? (clojure.lang.RT/aget buf idx)) 1.66 + (unchecked-inc count) 1.67 + count))) 1.68 + 1.69 + 1.70 + 1.71 + 1.72 + 1.73 + 1.74 + 1.75 + 1.76 + 1.77 + 1.78 + 1.79 +"(times are averages with 10 rounds) 1.80 +no-modifications 1.81 + classic: 198.151 1.82 + lite: 186.668 1.83 + 1.84 +unchecked-inc 1.85 + classic: 177.938 1.86 + lite: 129.604 1.87 + 1.88 +inlined-let 1.89 + classic: 202.604 1.90 + lite: 195.357 1.91 + 1.92 +make nl a constant 1.93 + classic: 1.94 + lite: 361.734 1.95 + 1.96 +make nl a constant with type hint 1.97 + lite: 394.45 1.98 + 1.99 +literal 10, no let 1.100 + lite: 102.876 1.101 + 1.102 + (int 10) instead of literal 10 1.103 + lite: 194.904 1.104 + 1.105 + (unchecked-add count 0) instead of count 1.106 + lite: 209.186 1.107 + 1.108 + direct reference to RT/aget, bypassing int cast 1.109 + lite: 99.767 1.110 + 1.111 + (int 0) instead of 0 initialization of count 1.112 + lite: 66.446 1.113 + 1.114 + make nl an (int 10) instead of (byte 10) 1.115 + lite: 180.003 1.116 +" 1.117 + 1.118 + 1.119 + 1.120 + 1.121 + 1.122 +(defmacro time-multi 1.123 + "Evaluates expr and prints the time it took. Returns the value of 1.124 + expr." 1.125 + {:added "1.0"} 1.126 + [expr] 1.127 + `(let [start# (. System (nanoTime)) 1.128 + ret# ~expr 1.129 + end# (/ (double (- (. System (nanoTime)) start#)) 1000000.0)] 1.130 + (prn (str "Elapsed time: " end# " msecs")) 1.131 + [ret# end#])) 1.132 + 1.133 + 1.134 + 1.135 +(defn run [countnl-impl] 1.136 + (let [ifs (FileInputStream. "/dev/urandom") 1.137 + buf (make-array Byte/TYPE *numbytes*) 1.138 + runs 10] 1.139 + (loop [n 0 total-time 0] 1.140 + (if (= n runs) (/ total-time runs) 1.141 + (let [sz (.read #^FileInputStream ifs buf)] 1.142 + (println "Wanted" *numbytes* "got" sz "bytes") 1.143 + (let [[count time] (time-multi (countnl-impl buf))] 1.144 + (println "Got" count "nls") 1.145 + (recur (inc n) (+ total-time time)))))))) 1.146 + 1.147 +(defn -main [& ignore] 1.148 + (run countnl-lite) 1.149 + (run countnl-classic) 1.150 + ) 1.151 + 1.152 + 1.153 +