view 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 source
1 (ns rlm.iterate
2 "from the clojure mailing list"
3 {:author "tsuraan"}
4 (:gen-class
5 :name "iterate"
6 :main true
7 ))
10 (set! *warn-on-reflection* true)
11 (import java.io.FileInputStream)
13 (def *numbytes* (* 16 1024 1024))
16 (defmacro better-areduce [a idx ret init expr]
17 `(let [a# ~a
18 alength# (alength a#)]
19 (loop [~idx (int 0) ~ret ~init]
20 (if (< ~idx alength#)
21 (recur (unchecked-inc ~idx) ~expr)
22 ~ret))))
24 (defn translated-countnl
25 [#^bytes buf]
26 (let [total-length (alength buf)]
27 (loop [count (int 0) current-index (int 0)]
28 (if (>= current-index total-length)
29 count
30 (let [new-count
31 (if (= (aget #^bytes buf current-index) (byte 10))
32 (unchecked-inc count)
33 count)]
35 (recur new-count (unchecked-inc current-index)))))))
37 (defn countnl-classic
38 [#^bytes buf]
39 (let [nl (byte 10)]
40 (areduce buf idx count 0
41 (if (= (aget buf idx) nl)
42 (inc count)
43 count))))
46 (defn countnl-lite
47 "this is the absolute fastest function I could come up with.
48 still 2.25 times slower that the java version."
49 [#^bytes buf]
50 (areduce buf idx count (int 0)
51 (if (= (clojure.lang.RT/aget buf idx) 10)
52 (unchecked-add count 1)
53 count)))
56 (defn #^Boolean is-ten? [#^Integer A]
57 (= A 10))
59 (defn countnl-max-power
60 [#^bytes buf]
61 (areduce buf idx count (int 0)
62 (if (is-ten? (clojure.lang.RT/aget buf idx))
63 (unchecked-inc count)
64 count)))
76 "(times are averages with 10 rounds)
77 no-modifications
78 classic: 198.151
79 lite: 186.668
81 unchecked-inc
82 classic: 177.938
83 lite: 129.604
85 inlined-let
86 classic: 202.604
87 lite: 195.357
89 make nl a constant
90 classic:
91 lite: 361.734
93 make nl a constant with type hint
94 lite: 394.45
96 literal 10, no let
97 lite: 102.876
99 (int 10) instead of literal 10
100 lite: 194.904
102 (unchecked-add count 0) instead of count
103 lite: 209.186
105 direct reference to RT/aget, bypassing int cast
106 lite: 99.767
108 (int 0) instead of 0 initialization of count
109 lite: 66.446
111 make nl an (int 10) instead of (byte 10)
112 lite: 180.003
113 "
119 (defmacro time-multi
120 "Evaluates expr and prints the time it took. Returns the value of
121 expr."
122 {:added "1.0"}
123 [expr]
124 `(let [start# (. System (nanoTime))
125 ret# ~expr
126 end# (/ (double (- (. System (nanoTime)) start#)) 1000000.0)]
127 (prn (str "Elapsed time: " end# " msecs"))
128 [ret# end#]))
132 (defn run [countnl-impl]
133 (let [ifs (FileInputStream. "/dev/urandom")
134 buf (make-array Byte/TYPE *numbytes*)
135 runs 10]
136 (loop [n 0 total-time 0]
137 (if (= n runs) (/ total-time runs)
138 (let [sz (.read #^FileInputStream ifs buf)]
139 (println "Wanted" *numbytes* "got" sz "bytes")
140 (let [[count time] (time-multi (countnl-impl buf))]
141 (println "Got" count "nls")
142 (recur (inc n) (+ total-time time))))))))
144 (defn -main [& ignore]
145 (run countnl-lite)
146 (run countnl-classic)
147 )