mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-26 18:08:34 -05:00
176 lines
5.1 KiB
Clojure
176 lines
5.1 KiB
Clojure
|
|
|
|
(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*)
|
|
|