3 (add-classpath "file:///Users/ragge/Projects/clojure/redis-clojure/redis-clojure.jar")
6 (:use clojure.contrib.pprint)
9 (defstruct benchmark-options
33 (defmacro defbenchmark [name & body]
34 (let [benchmark-name (symbol (str name "-benchmark"))]
35 `(def ~(with-meta benchmark-name {:benchmark true})
37 [client# options# result#]
39 {:host (options# :host)
40 :port (options# :port)
42 (let [requests# (:requests options#)
43 requests-done# (:requests result#)]
44 (loop [requests-performed# 0 request-times# []]
45 (if (>= @requests-done# requests#)
47 :request-times request-times#
48 :requests-performed requests-performed#)
50 (let [start# (System/nanoTime)]
52 (let [end# (System/nanoTime)
53 elapsed# (/ (float (- end# start#)) 1000000.0)]
55 (commute requests-done# inc))
56 (recur (inc requests-performed#)
57 (conj request-times# elapsed#)))))))))))))
63 (redis/get (str "key-" (rand-int 1000))))
66 (redis/set (str "key-" (rand-int 1000)) "abc"))
68 (defbenchmark exists-set-and-get
69 (let [key (str "key-" (rand-int 100))]
71 (redis/set key "blahongaa!")
75 (def *default-options* (struct-map benchmark-options
82 (defn create-clients [options]
83 (for [id (range (:clients options))]
84 (agent (struct client id))))
86 (defn create-result [options clients]
87 (let [result (struct result options clients 0 (ref 0))]
91 (defn requests-by-ms [clients]
92 (let [all-times (apply concat (map #(:request-times (deref %)) clients))
93 all-times-in-ms (map #(int (/ % 1)) all-times)]
98 (assoc m time (inc (m time)))
100 {} all-times-in-ms))))
102 (defn report-request-times [clients requests]
103 (let [requests-dist (map #(let [perc (* 100 (/ (last %) requests))]
104 (conj % perc)) (requests-by-ms clients))]
105 (loop [items requests-dist
107 (if-not (empty? items)
109 (let [item (first items)
110 seen (+ seen (last item))]
111 (println (format "%.2f%% < %d ms" (float seen) (inc (first item))))
112 (recur (rest items) seen)))))))
114 (defn report-client-rps [client]
115 (let [{:keys [id requests-performed request-times]} @client]
116 (when (< 0 requests-performed)
117 (let [total-time (apply + request-times)
118 requests-per-second (/ (float requests-performed)
121 (println (format "Client %d: %f rps" id (float requests-per-second)))))))
123 (defn report-result [result]
124 (let [{:keys [clients options]} result
126 time (:total-time result)
127 time-in-seconds (/ time 1000)
128 requests (deref (:requests result))
129 requests-per-second (/ requests time-in-seconds)
132 (println (format "====== %s =====\n" name))
133 (println (format " %d requests completed in %f seconds\n" requests time-in-seconds))
134 (println (format " %d parallel clients\n" (:clients options)))
135 (report-request-times clients requests)
136 ;(dorun (map report-client-rps clients))
137 (println (format "%f requests per second\n\n" requests-per-second))
144 (defn run-benchmark [fn options]
145 (let [clients (create-clients options)
146 result (create-result options clients)
147 start (System/nanoTime)]
149 (map #(send-off % fn options result) clients))
150 (apply await clients)
151 (let [elapsed (/ (double (- (System/nanoTime) start)) 1000000.0)]
153 (map #(when (agent-errors %)
154 (pprint (agent-errors %))) clients))
159 :total-time elapsed))))
161 (defn find-all-benchmarks [ns]
162 (filter #(:benchmark (meta %))
165 (defn run-and-report [fn options]
166 (let [result (run-benchmark fn options)]
167 (report-result result)))
169 (defn run-all-benchmarks [ns]
170 (let [benchmarks (find-all-benchmarks ns)]
172 (map #(run-and-report % *default-options*) benchmarks))))
175 ;(run-all-benchmarks)
177 ;(report-result (run-benchmark ping-benchmark *default-options*))
178 ;(run-benchmark get-benchmark *default-options*)