Mercurial > rlm
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:78a630e650d2 |
---|---|
1 (ns rlm.iterate | |
2 "from the clojure mailing list" | |
3 {:author "tsuraan"} | |
4 (:gen-class | |
5 :name "iterate" | |
6 :main true | |
7 )) | |
8 | |
9 | |
10 (set! *warn-on-reflection* true) | |
11 (import java.io.FileInputStream) | |
12 | |
13 (def *numbytes* (* 16 1024 1024)) | |
14 | |
15 | |
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)))) | |
23 | |
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)] | |
34 | |
35 (recur new-count (unchecked-inc current-index))))))) | |
36 | |
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)))) | |
44 | |
45 | |
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))) | |
54 | |
55 | |
56 (defn #^Boolean is-ten? [#^Integer A] | |
57 (= A 10)) | |
58 | |
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))) | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 "(times are averages with 10 rounds) | |
77 no-modifications | |
78 classic: 198.151 | |
79 lite: 186.668 | |
80 | |
81 unchecked-inc | |
82 classic: 177.938 | |
83 lite: 129.604 | |
84 | |
85 inlined-let | |
86 classic: 202.604 | |
87 lite: 195.357 | |
88 | |
89 make nl a constant | |
90 classic: | |
91 lite: 361.734 | |
92 | |
93 make nl a constant with type hint | |
94 lite: 394.45 | |
95 | |
96 literal 10, no let | |
97 lite: 102.876 | |
98 | |
99 (int 10) instead of literal 10 | |
100 lite: 194.904 | |
101 | |
102 (unchecked-add count 0) instead of count | |
103 lite: 209.186 | |
104 | |
105 direct reference to RT/aget, bypassing int cast | |
106 lite: 99.767 | |
107 | |
108 (int 0) instead of 0 initialization of count | |
109 lite: 66.446 | |
110 | |
111 make nl an (int 10) instead of (byte 10) | |
112 lite: 180.003 | |
113 " | |
114 | |
115 | |
116 | |
117 | |
118 | |
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#])) | |
129 | |
130 | |
131 | |
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)))))))) | |
143 | |
144 (defn -main [& ignore] | |
145 (run countnl-lite) | |
146 (run countnl-classic) | |
147 ) | |
148 | |
149 | |
150 |