From e7bf1000b9474c2e93c397a63c169c3454c19595 Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Mon, 14 Jan 2019 21:53:37 +0200 Subject: [PATCH] More perf docs --- CHANGELOG.md | 8 ++++++++ doc/performance.md | 28 ++++++++++++++++++++++++++++ doc/ring/ring.md | 8 +++++--- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6c8ffe1..28bf4569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ * `reitit.core/Expand` can be extended, fixes [#201](https://github.com/metosin/reitit/issues/201). * new snappy Java-backed `SegmentTrie` routing algorithm, wildcard routing is ~2x faster on the JVM +### `reitit-ring` + +* new options `:inject-match?` and `:inject-router?` on `reitit.ring/ring-handler` to optionally not to inject `Router` and `Match` into the request. See [performance guide](https://metosin.github.io/reitit/performance.html#faster!) for details. + +### `reitit-http` + +* new options `:inject-match?` and `:inject-router?` on `reitit.http/ring-handler` and `reitit.http/routing-interceptor` to optionally not to inject `Router` and `Match` into the request. See [performance guide](https://metosin.github.io/reitit/performance.html#faster!) for details. + ## 0.2.10 (2018-12-30) ### `reitit-core` diff --git a/doc/performance.md b/doc/performance.md index 466f0b39..13d9491f 100644 --- a/doc/performance.md +++ b/doc/performance.md @@ -101,6 +101,34 @@ The reitit routing perf is measured to get an internal baseline to optimize agai A quick poke to [routers in Go](https://github.com/julienschmidt/go-http-routing-benchmark) indicates that the reitit is only few times slower than the fastest routers in Go. Which is kinda awesome. +### Faster! + +By default, `reitit.ring/ring-router`, `reitit.http/ring-router` and `reitit.http/routing-interceptor` inject both `Match` and `Router` into the request. You can remove the injections setting options `:inject-match?` and `:inject-router?` to `false`. This saves some tens of nanos (with the hw described above). + +```clj +(require '[reitit.ring :as ring]) +(require '[criterium.core :as cc]) + +(defn create [options] + (ring/ring-handler + (ring/router + ["/ping" (constantly {:status 200, :body "ok"})]) + (ring/create-default-handler) + options)) + +;; 130ns +(let [app (create nil)] + (cc/quick-bench + (app {:request-method :get, :uri "/ping"}))) + +;; 80ns +(let [app (create {:inject-router? false, :inject-match? false})] + (cc/quick-bench + (app {:request-method :get, :uri "/ping"}))) +``` + +**NOTE**: Without `Router`, you can't to do [reverse routing](ring/reverse_routing.md) and without `Match` you can't write [dynamic extensions](ring/dynamic_extensions.md). + ### Performance tips Few things that have an effect on performance: diff --git a/doc/ring/ring.md b/doc/ring/ring.md index ff1f5deb..2356d0b5 100644 --- a/doc/ring/ring.md +++ b/doc/ring/ring.md @@ -51,9 +51,11 @@ Match contains `:result` compiled by the `ring-router`: Given a `ring-router`, optional default-handler & options, `ring-handler` function will return a valid ring handler supporting both synchronous and [asynchronous](https://www.booleanknot.com/blog/2016/07/15/asynchronous-ring.html) request handling. The following options are available: -| key | description | -| --------------|-------------| -| `:middleware` | Optional sequence of middleware that wrap the ring-handler" +| key | description | +| ------------------|-------------| +| `:middleware` | Optional sequence of middleware that wrap the ring-handler" +| `:inject-match?` | Boolean to inject `match` into request under `:reitit.core/match` key (default true) +| `:inject-router?` | Boolean to inject `router` into request under `:reitit.core/router` key (default true) Simple Ring app: