Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add documentation to perf ns, and add sleep arg to decrease GC's affe…

…ct on timings.
  • Loading branch information...
commit bb3a2aa1f5692131f109371d511af558aa8b680e 1 parent b916876
Alexander Taggart authored
Showing with 69 additions and 23 deletions.
  1. +69 −23 src/test/clojure/clojure/data/codec/perf_base64.clj
View
92 src/test/clojure/clojure/data/codec/perf_base64.clj
@@ -4,58 +4,85 @@
[clojure.string :as str])
(:use clojure.data.codec.base64))
+(comment ;Example usage
+(gen-data-file "data.in" 1 12 20) ; generate the data file to be used
+(init-time-file "data.in" "time.out" 100) ; initialize timing file
+(run-perf "data.in" "time.out" 100 false) ; add timings for (encode ...)
+(run-perf "data.in" "time.out" 100 true) ; add timings for (encode! ...)
+)
+
(set! *warn-on-reflection* true)
-(defn rand-bytes [n]
+(defn rand-bytes
+ "Returns a randomly populated byte-array of length n."
+ [n]
(->> #(byte (- (rand-int 256) 128))
repeatedly
(take n)
(byte-array)))
-(defn gen-data-file [file from to times]
+(defn gen-data-file
+ "Prints to file randomly generated byte vectors between lengths from and to,
+ inclusive, with times number of each length."
+ [file from to times]
(with-open [w (PrintWriter. (io/writer file))]
(binding [*out* w]
(doseq [n (range from (inc to))]
(doseq [_ (range 0 times)]
(println (into [] (rand-bytes n))))))))
-(defn read-data-file [file]
+(defn read-data-file
+ "Lazily reads a data file, returning a lazy sequence of byte-arrays."
+ [file]
(->> (line-seq (io/reader file))
(map read-string)
(map #(map byte %))
(map byte-array)))
-(defmacro time-it [expr]
+(defmacro time-it
+ "Like clojure.core/time, but returns the time in nanos instead of printing it."
+ [expr]
`(let [start# (System/nanoTime)
_# ~expr
stop# (System/nanoTime)]
(- stop# start#)))
-(defn perf-clj [bas]
+(defn perf-clj
+ "Returns a lazy sequence of encode timings for the given sequence of byte arrays."
+ [bas sleep]
(for [ba bas]
(do
- (Thread/sleep 100)
+ (Thread/sleep sleep)
(time-it (encode ba)))))
-(defn perf-clj-buf [bas]
+(defn perf-clj-buf
+ "Returns a lazy sequence of encode! timings for the given sequence of byte arrays."
+ [bas sleep]
(let [out (memoize (fn [n] (byte-array (enc-length n))))]
(for [^bytes ba bas]
(let [len (alength ba)
output (out len)]
(do
- (Thread/sleep 100)
+ (Thread/sleep sleep)
(time-it (encode! ba 0 len output)))))))
-(defn perf-apache [bas]
+(defn perf-apache
+ "Returns a lazy sequence of apache base64 encode timings for the given sequence of
+ byte arrays."
+ [bas sleep]
(for [ba bas]
(do
- (Thread/sleep 100)
+ (Thread/sleep sleep)
(time-it (Base64/encodeBase64 ba)))))
-(defn append-times [table times]
+(defn append-times
+ "Lazily adds a column of timings to the given table."
+ [table times]
(map (fnil conj []) table times))
-(defn write-time-file [table file]
+(defn write-time-file
+ "Writes a table of timings to file."
+ [table file]
(with-open [w (PrintWriter. (io/writer file))]
(binding [*out* w]
(doseq [row table]
@@ -65,17 +92,20 @@
(print e))
(println)))))
-(defn read-time-file [file]
+(defn read-time-file
+ "Lazily reads a file containing a table of timings."
+ [file]
(->> (line-seq (io/reader file))
(map #(str/split % #"\t"))
(map vec)))
-(defn init-perf-apache [bas]
- (map #(vector (count %1) %2) bas (perf-apache bas)))
(defn third [[_ _ x]] x)
-(defn latest-time-file [basis]
+(defn latest-time-file
+ "Returns the name of the latest enumerated file with the given basis, or nil if it
+ doesn't exist."
+ [basis]
(let [dir (io/file ".")
nums (->> (.list dir )
(filter #(.startsWith ^String % basis))
@@ -86,22 +116,38 @@
(if (seq nums)
(format "%s.%03d" basis (apply max nums)))))
-(defn next-time-file [file]
+(defn next-time-file
+ "Returns the name of the next enumerated file after the given enumerated file name."
+ [file]
(if-let [[_ prefix suffix] (re-matches #"(.+\.)([0-9]{3})" file)]
(format "%s%03d" prefix (inc (Integer/parseInt suffix)))))
-(defn init-time-file [data-file time-file]
- (write-time-file (init-perf-apache (read-data-file data-file)) (str time-file ".000")))
-
-(defn run-perf [data-file time-file use-buffer?]
+(defn init-perf-apache
+ "Returns a lazy sequence of [count apache-timing] for each byte-array."
+ [bas sleep]
+ (map #(vector (count %1) %2) bas (perf-apache bas sleep)))
+
+(defn init-time-file
+ "Using the given data file, creates a timing file using apache base64 encoding.
+ Sleep specifies the delay between iterations, thus reducing the chance of delays
+ from GC affecting the timing."
+ [data-file time-file sleep]
+ (write-time-file (init-perf-apache (read-data-file data-file) sleep) (str time-file ".000")))
+
+(defn run-perf
+ "Using the given data file, adds a column of clojure base64 encode times to the
+ specified timing file. If use-buffer? is true, encode! will be used instead.
+ Sleep specifies the delay between iterations, thus reducing the chance of delays
+ from GC affecting the timing."
+ [data-file time-file sleep use-buffer?]
(let [prev-time-file (latest-time-file time-file)
next-time-file (next-time-file prev-time-file)]
(write-time-file
(append-times
(read-time-file prev-time-file)
(if use-buffer?
- (perf-clj-buf (read-data-file data-file))
- (perf-clj (read-data-file data-file))))
+ (perf-clj-buf (read-data-file data-file) sleep)
+ (perf-clj (read-data-file data-file) sleep)))
next-time-file)))
Please sign in to comment.
Something went wrong with that request. Please try again.