X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/c9a111acf47cb5bb2138d1f699253f87d68e53e8..e59229a2d540b00566f44c8f29764de3ae89b5be:/client-libraries/clojure/benchmarks/clojure.clj diff --git a/client-libraries/clojure/benchmarks/clojure.clj b/client-libraries/clojure/benchmarks/clojure.clj new file mode 100644 index 00000000..7f88d8ea --- /dev/null +++ b/client-libraries/clojure/benchmarks/clojure.clj @@ -0,0 +1,175 @@ + + +(add-classpath "file:///Users/ragge/Projects/clojure/redis-clojure/redis-clojure.jar") + +(ns benchmarks.clojure + (:use clojure.contrib.pprint) + (:require redis)) + +(defstruct benchmark-options + :host + :port + :db + :clients + :requests + :key-size + :keyspace-size + :data-size) + + +(defstruct client + :id + :request-times + :requests-performed + :requests-per-second) + +(defstruct result + :options + :clients + :total-time + :requests) + + + +(defmacro defbenchmark [name & body] + (let [benchmark-name (symbol (str name "-benchmark"))] + `(def ~(with-meta benchmark-name {:benchmark true}) + (fn ~benchmark-name + [client# options# result#] + (redis/with-server + {:host (options# :host) + :port (options# :port) + :db (options# :db)} + (let [requests# (:requests options#) + requests-done# (:requests result#)] + (loop [requests-performed# 0 request-times# []] + (if (>= @requests-done# requests#) + (assoc client# + :request-times request-times# + :requests-performed requests-performed#) + (do + (let [start# (System/nanoTime)] + ~@body + (let [end# (System/nanoTime) + elapsed# (/ (float (- end# start#)) 1000000.0)] + (dosync + (commute requests-done# inc)) + (recur (inc requests-performed#) + (conj request-times# elapsed#))))))))))))) + +(defbenchmark ping + (redis/ping)) + +(defbenchmark get + (redis/get (str "key-" (rand-int 1000)))) + +(defbenchmark set + (redis/set (str "key-" (rand-int 1000)) "blahojga!")) + +(defbenchmark exists-set-and-get + (let [key (str "key-" (rand-int 100))] + (redis/exists key) + (redis/set key "blahongaa!") + (redis/get key))) + + +(def *default-options* (struct-map benchmark-options + :host "127.0.0.1" + :port 6379 + :db 15 + :clients 4 + :requests 10000)) + +(defn create-clients [options] + (for [id (range (:clients options))] + (agent (struct client id)))) + +(defn create-result [options clients] + (let [result (struct result options clients 0 (ref 0))] + result)) + + +(defn requests-by-ms [clients] + (let [all-times (apply concat (map #(:request-times (deref %)) clients)) + all-times-in-ms (map #(int (/ % 1)) all-times)] + (sort + (reduce + (fn [m time] + (if (m time) + (assoc m time (inc (m time))) + (assoc m time 1))) + {} all-times-in-ms)))) + +(defn report-request-times [clients requests] + (let [requests-dist (map #(let [perc (* 100 (/ (last %) requests))] + (conj % perc)) (requests-by-ms clients))] + (dorun + (map #(println (format "%.2f%% < %d ms" (float (last %)) (inc (first %)))) + requests-dist)))) + +(defn report-client-rps [client] + (let [{:keys [id requests-performed request-times]} @client] + (when (< 0 requests-performed) + (let [total-time (apply + request-times) + requests-per-second (/ (float requests-performed) + total-time)] + (println total-time) + (println (format "Client %d: %f rps" id (float requests-per-second))))))) + +(defn report-result [result] + (let [{:keys [clients options]} result + name (:name result) + time (:total-time result) + time-in-seconds (/ time 1000) + requests (deref (:requests result)) + requests-per-second (/ requests time-in-seconds) + ] + (do + (println (format "====== %s =====\n" name)) + (println (format " %d requests completed in %f seconds\n" requests time-in-seconds)) + (println (format " %d parallel clients\n" (:clients options))) + ;(report-request-times clients requests) + ;(dorun (map report-client-rps clients)) + (println (format "%f requests per second\n\n" requests-per-second)) + ) + ) + ) + + + +(defn run-benchmark [fn options] + (let [clients (create-clients options) + result (create-result options clients) + start (System/nanoTime)] + (dorun + (map #(send-off % fn options result) clients)) + (apply await clients) + (let [elapsed (/ (double (- (System/nanoTime) start)) 1000000.0)] + (dorun + (map #(when (agent-errors %) + (pprint (agent-errors %))) clients)) + (assoc result + :name (str fn) + :options options + :clients clients + :total-time elapsed)))) + +(defn find-all-benchmarks [ns] + (filter #(:benchmark (meta %)) + (vals (ns-map ns)))) + +(defn run-and-report [fn options] + (let [result (run-benchmark fn options)] + (report-result result))) + +(defn run-all-benchmarks [ns] + (let [benchmarks (find-all-benchmarks ns)] + (dorun + (map #(run-and-report % *default-options*) benchmarks)))) + + +;(run-all-benchmarks) + +;(report-result (run-benchmark ping-benchmark *default-options*)) +;(run-benchmark get-benchmark *default-options*) +