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