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 +