mirror of
https://github.com/fluencelabs/redis
synced 2025-06-17 11:11:20 +00:00
Clojure library thanks to Ragnar Dahlén
This commit is contained in:
175
client-libraries/clojure/benchmarks/clojure.clj
Normal file
175
client-libraries/clojure/benchmarks/clojure.clj
Normal file
@ -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*)
|
||||
|
Reference in New Issue
Block a user