diff --git a/perf-test/clj/reitit/go_perf_test.clj b/perf-test/clj/reitit/go_perf_test.clj new file mode 100644 index 00000000..4a7c2790 --- /dev/null +++ b/perf-test/clj/reitit/go_perf_test.clj @@ -0,0 +1,110 @@ +(ns reitit.go-perf-test + (:require [criterium.core :as cc] + [reitit.perf-utils :refer :all] + [reitit.ring :as ring] + [clojure.string :as str])) + +;; +;; start repl with `lein perf repl` +;; perf measured with the following setup: +;; +;; Model Name: MacBook Pro +;; Model Identifier: MacBookPro113 +;; Processor Name: Intel Core i7 +;; Processor Speed: 2,5 GHz +;; Number of Processors: 1 +;; Total Number of Cores: 4 +;; L2 Cache (per Core): 256 KB +;; L3 Cache: 6 MB +;; Memory: 16 GB +;; + +(defn h [path] + (fn [req] + {:status 200, :body path})) + +(defn add [handler routes route] + (let [method (-> route keys first str/lower-case keyword) + path (-> route vals first) + h (handler path)] + (if (some (partial = path) (map first routes)) + (mapv (fn [[p d]] (if (= path p) [p (assoc d method h)] [p d])) routes) + (conj routes [path {method h}])))) + +(def routes [{"POST", "/1/classes/:className"}, + {"GET", "/1/classes/:className/:objectId"}, + {"PUT", "/1/classes/:className/:objectId"}, + {"GET", "/1/classes/:className"}, + {"DELETE", "/1/classes/:className/:objectId"}, + + ;; Users + {"POST", "/1/users"}, + {"GET", "/1/login"}, + {"GET", "/1/users/:objectId"}, + {"PUT", "/1/users/:objectId"}, + {"GET", "/1/users"}, + {"DELETE", "/1/users/:objectId"}, + {"POST", "/1/requestPasswordReset"}, + + ;; Roles + {"POST", "/1/roles"}, + {"GET", "/1/roles/:objectId"}, + {"PUT", "/1/roles/:objectId"}, + {"GET", "/1/roles"}, + {"DELETE", "/1/roles/:objectId"}, + + ;; Files + {"POST", "/1/files/:fileName"}, + + ;; Analytics + {"POST", "/1/events/:eventName"}, + + ;; Push Notifications + {"POST", "/1/push"}, + + ;; Installations + {"POST", "/1/installations"}, + {"GET", "/1/installations/:objectId"}, + {"PUT", "/1/installations/:objectId"}, + {"GET", "/1/installations"}, + {"DELETE", "/1/installations/:objectId"}, + + ;; Cloud Functions + {"POST", "/1/functions"}]) + + +(def app + (ring/ring-handler + (ring/router + (reduce (partial add h) [] routes)))) + +(defn routing-test [] + ;; https://github.com/julienschmidt/go-http-routing-benchmark + ;; coudn't run the GO tests, so reusing just the numbers (run on better hw?): + ;; + ;; Intel Core i5-2500K (4x 3,30GHz + Turbo Boost), CPU-governor: performance + ;; 2x 4 GiB DDR3-1333 RAM, dual-channel + ;; go version go1.3rc1 linux/amd64 + ;; Ubuntu 14.04 amd64 (Linux Kernel 3.13.0-29), fresh installation + + ;; 37ns (2.0x) + ;; 180ns (4.0x) + ;; 200ns (4.8x) + "httpRouter" + + ;; 77ns + ;; 730ns + ;; 960ns + (title "reitit-ring") + (let [r1 (map->Request {:request-method :get, :uri "/1/users"}) + r2 (map->Request {:request-method :get, :uri "/1/classes/go"}) + r3 (map->Request {:request-method :get, :uri "/1/classes/go/123456789"})] + (assert (= {:status 200, :body "/1/users"} (app r1))) + (assert (= {:status 200, :body "/1/classes/:className"} (app r2))) + (assert (= {:status 200, :body "/1/classes/:className/:objectId"} (app r3))) + (cc/quick-bench (app r1)) + (cc/quick-bench (app r2)) + (cc/quick-bench (app r3)))) + +(comment + (routing-test)) diff --git a/perf-test/clj/reitit/nodejs_perf_test.clj b/perf-test/clj/reitit/nodejs_perf_test.clj new file mode 100644 index 00000000..fd31d31b --- /dev/null +++ b/perf-test/clj/reitit/nodejs_perf_test.clj @@ -0,0 +1,82 @@ +(ns reitit.nodejs-perf-test + (:require [criterium.core :as cc] + [reitit.perf-utils :refer :all] + [immutant.web :as web] + [reitit.ring :as ring])) + +;; +;; start repl with `lein perf repl` +;; perf measured with the following setup: +;; +;; Model Name: MacBook Pro +;; Model Identifier: MacBookPro113 +;; Processor Name: Intel Core i7 +;; Processor Speed: 2,5 GHz +;; Number of Processors: 1 +;; Total Number of Cores: 4 +;; L2 Cache (per Core): 256 KB +;; L3 Cache: 6 MB +;; Memory: 16 GB +;; + +(defn h [name req] + (let [id (-> req :path-params :id)] + {:status 200, :body (str "Got " name " id " id)})) + + +(def app + (ring/ring-handler + (ring/router + (for [name ["product" "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "twenty"]] + [(str "/" name "/:id") {:get (partial h name)}])))) + +(app {:request-method :get, :uri "/product/foo"}) + +(defn routing-test [] + + ;; 21385 / 14337 + "barista" + + ;; 26259 / 25571 + "choreographer" + + ;; 24277 / 19174 + "clutch" + + ;; 26158 / 25584 + "connect" + + ;; 24614 / 25413 + "escort" + + ;; 21979 / 18595 + "express" + + ;; 23123 / 25405 + "find-my-way" + + ;; 24798 / 25286 + "http-hash" + + ;; 24215 / 23670 + "i40" + + ;; 23561 / 26278 + "light-router" + + ;; 28362 / 30056 + "http-raw" + + ;; 25310 / 25126 + "regex" + + ;; 84149 / 84867 + (title "reitit") + ;; wrk -d ${DURATION:="30s"} http://127.0.0.1:2048/product/foo + ;; wrk -d ${DURATION:="30s"} http://127.0.0.1:2048/twenty/bar + (assert (= {:status 200, :body "Got product id foo"} (app {:request-method :get, :uri "/product/foo"}))) + (assert (= {:status 200, :body "Got twenty id bar"} (app {:request-method :get, :uri "/twenty/bar"})))) + +(comment + (web/run app {:port 2048}) + (routing-test)) diff --git a/project.clj b/project.clj index 81402f3a..21760d71 100644 --- a/project.clj +++ b/project.clj @@ -58,6 +58,7 @@ "-Dclojure.compiler.direct-linking=true"] :test-paths ["perf-test/clj"] :dependencies [[compojure "1.6.0"] + [org.immutant/immutant "2.1.9"] [io.pedestal/pedestal.route "0.5.3"] [org.clojure/core.async "0.3.443"] [ataraxy "0.4.0"]