]> git.saurik.com Git - redis.git/blame - client-libraries/clojure/benchmarks/clojure.clj
client libraries updated
[redis.git] / client-libraries / clojure / benchmarks / clojure.clj
CommitLineData
e59229a2 1
2
3(add-classpath "file:///Users/ragge/Projects/clojure/redis-clojure/redis-clojure.jar")
4
5(ns benchmarks.clojure
6 (:use clojure.contrib.pprint)
7 (:require redis))
8
9(defstruct benchmark-options
10 :host
11 :port
12 :db
13 :clients
14 :requests
15 :key-size
16 :keyspace-size
17 :data-size)
18
19
20(defstruct client
21 :id
22 :request-times
23 :requests-performed
24 :requests-per-second)
25
26(defstruct result
27 :options
28 :clients
29 :total-time
30 :requests)
31
32
e59229a2 33(defmacro defbenchmark [name & body]
34 (let [benchmark-name (symbol (str name "-benchmark"))]
35 `(def ~(with-meta benchmark-name {:benchmark true})
36 (fn ~benchmark-name
37 [client# options# result#]
38 (redis/with-server
39 {:host (options# :host)
40 :port (options# :port)
41 :db (options# :db)}
42 (let [requests# (:requests options#)
43 requests-done# (:requests result#)]
44 (loop [requests-performed# 0 request-times# []]
45 (if (>= @requests-done# requests#)
46 (assoc client#
47 :request-times request-times#
48 :requests-performed requests-performed#)
49 (do
50 (let [start# (System/nanoTime)]
51 ~@body
52 (let [end# (System/nanoTime)
53 elapsed# (/ (float (- end# start#)) 1000000.0)]
54 (dosync
55 (commute requests-done# inc))
56 (recur (inc requests-performed#)
57 (conj request-times# elapsed#)))))))))))))
58
59(defbenchmark ping
60 (redis/ping))
61
62(defbenchmark get
63 (redis/get (str "key-" (rand-int 1000))))
64
65(defbenchmark set
111d9959 66 (redis/set (str "key-" (rand-int 1000)) "abc"))
e59229a2 67
68(defbenchmark exists-set-and-get
69 (let [key (str "key-" (rand-int 100))]
70 (redis/exists key)
71 (redis/set key "blahongaa!")
72 (redis/get key)))
73
74
75(def *default-options* (struct-map benchmark-options
76 :host "127.0.0.1"
77 :port 6379
78 :db 15
111d9959 79 :clients 1
e59229a2 80 :requests 10000))
81
82(defn create-clients [options]
83 (for [id (range (:clients options))]
84 (agent (struct client id))))
85
86(defn create-result [options clients]
87 (let [result (struct result options clients 0 (ref 0))]
88 result))
89
90
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)]
94 (sort
95 (reduce
96 (fn [m time]
97 (if (m time)
98 (assoc m time (inc (m time)))
99 (assoc m time 1)))
100 {} all-times-in-ms))))
101
102(defn report-request-times [clients requests]
103 (let [requests-dist (map #(let [perc (* 100 (/ (last %) requests))]
104 (conj % perc)) (requests-by-ms clients))]
111d9959 105 (loop [items requests-dist
106 seen 0]
107 (if-not (empty? items)
108 (do
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)))))))
e59229a2 113
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)
119 total-time)]
120 (println total-time)
121 (println (format "Client %d: %f rps" id (float requests-per-second)))))))
122
123(defn report-result [result]
124 (let [{:keys [clients options]} result
125 name (:name 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)
130 ]
131 (do
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)))
111d9959 135 (report-request-times clients requests)
e59229a2 136 ;(dorun (map report-client-rps clients))
137 (println (format "%f requests per second\n\n" requests-per-second))
138 )
139 )
140 )
141
142
143
144(defn run-benchmark [fn options]
145 (let [clients (create-clients options)
146 result (create-result options clients)
147 start (System/nanoTime)]
148 (dorun
149 (map #(send-off % fn options result) clients))
150 (apply await clients)
151 (let [elapsed (/ (double (- (System/nanoTime) start)) 1000000.0)]
152 (dorun
153 (map #(when (agent-errors %)
154 (pprint (agent-errors %))) clients))
155 (assoc result
156 :name (str fn)
157 :options options
158 :clients clients
159 :total-time elapsed))))
160
161(defn find-all-benchmarks [ns]
162 (filter #(:benchmark (meta %))
163 (vals (ns-map ns))))
164
165(defn run-and-report [fn options]
166 (let [result (run-benchmark fn options)]
167 (report-result result)))
168
169(defn run-all-benchmarks [ns]
170 (let [benchmarks (find-all-benchmarks ns)]
171 (dorun
172 (map #(run-and-report % *default-options*) benchmarks))))
173
174
175;(run-all-benchmarks)
176
177;(report-result (run-benchmark ping-benchmark *default-options*))
178;(run-benchmark get-benchmark *default-options*)
179