3 (add-classpath "file:///Users/ragge/Projects/clojure/redis-clojure/redis-clojure.jar")
6 (:use clojure.contrib.pprint)
9 (defstruct benchmark-options
34 (defmacro defbenchmark [name & body]
35 (let [benchmark-name (symbol (str name "-benchmark"))]
36 `(def ~(with-meta benchmark-name {:benchmark true})
38 [client# options# result#]
40 {:host (options# :host)
41 :port (options# :port)
43 (let [requests# (:requests options#)
44 requests-done# (:requests result#)]
45 (loop [requests-performed# 0 request-times# []]
46 (if (>= @requests-done# requests#)
48 :request-times request-times#
49 :requests-performed requests-performed#)
51 (let [start# (System/nanoTime)]
53 (let [end# (System/nanoTime)
54 elapsed# (/ (float (- end# start#)) 1000000.0)]
56 (commute requests-done# inc))
57 (recur (inc requests-performed#)
58 (conj request-times# elapsed#)))))))))))))
64 (redis/get (str "key-" (rand-int 1000))))
67 (redis/set (str "key-" (rand-int 1000)) "blahojga!"))
69 (defbenchmark exists-set-and-get
70 (let [key (str "key-" (rand-int 100))]
72 (redis/set key "blahongaa!")
76 (def *default-options* (struct-map benchmark-options
83 (defn create-clients [options]
84 (for [id (range (:clients options))]
85 (agent (struct client id))))
87 (defn create-result [options clients]
88 (let [result (struct result options clients 0 (ref 0))]
92 (defn requests-by-ms [clients]
93 (let [all-times (apply concat (map #(:request-times (deref %)) clients))
94 all-times-in-ms (map #(int (/ % 1)) all-times)]
99 (assoc m time (inc (m time)))
101 {} all-times-in-ms))))
103 (defn report-request-times [clients requests]
104 (let [requests-dist (map #(let [perc (* 100 (/ (last %) requests))]
105 (conj % perc)) (requests-by-ms clients))]
107 (map #(println (format "%.2f%% < %d ms" (float (last %)) (inc (first %))))
110 (defn report-client-rps [client]
111 (let [{:keys [id requests-performed request-times]} @client]
112 (when (< 0 requests-performed)
113 (let [total-time (apply + request-times)
114 requests-per-second (/ (float requests-performed)
117 (println (format "Client %d: %f rps" id (float requests-per-second)))))))
119 (defn report-result [result]
120 (let [{:keys [clients options]} result
122 time (:total-time result)
123 time-in-seconds (/ time 1000)
124 requests (deref (:requests result))
125 requests-per-second (/ requests time-in-seconds)
128 (println (format "====== %s =====\n" name))
129 (println (format " %d requests completed in %f seconds\n" requests time-in-seconds))
130 (println (format " %d parallel clients\n" (:clients options)))
131 ;(report-request-times clients requests)
132 ;(dorun (map report-client-rps clients))
133 (println (format "%f requests per second\n\n" requests-per-second))
140 (defn run-benchmark [fn options]
141 (let [clients (create-clients options)
142 result (create-result options clients)
143 start (System/nanoTime)]
145 (map #(send-off % fn options result) clients))
146 (apply await clients)
147 (let [elapsed (/ (double (- (System/nanoTime) start)) 1000000.0)]
149 (map #(when (agent-errors %)
150 (pprint (agent-errors %))) clients))
155 :total-time elapsed))))
157 (defn find-all-benchmarks [ns]
158 (filter #(:benchmark (meta %))
161 (defn run-and-report [fn options]
162 (let [result (run-benchmark fn options)]
163 (report-result result)))
165 (defn run-all-benchmarks [ns]
166 (let [benchmarks (find-all-benchmarks ns)]
168 (map #(run-and-report % *default-options*) benchmarks))))
171 ;(run-all-benchmarks)
173 ;(report-result (run-benchmark ping-benchmark *default-options*))
174 ;(run-benchmark get-benchmark *default-options*)