mirror of
https://github.com/metosin/reitit.git
synced 2025-12-30 13:18:25 +00:00
20% faster wildcard parameters with records
This commit is contained in:
parent
55a5133e85
commit
e41a50cb80
5 changed files with 33 additions and 6 deletions
|
|
@ -80,6 +80,7 @@
|
|||
| key | description |
|
||||
| -----------------------------|-------------|
|
||||
| `:reitit.trie/trie-compiler` | Optional trie-compiler.
|
||||
| `:reitit.trie/parameters` | Optional function to transform path-parameters at creation time (default `identity`)."
|
||||
([compiled-routes]
|
||||
(linear-router compiled-routes {}))
|
||||
([compiled-routes opts]
|
||||
|
|
@ -91,7 +92,7 @@
|
|||
f #(if-let [path (impl/path-for route %)]
|
||||
(->Match p data result (impl/url-decode-coll %) path)
|
||||
(->PartialMatch p data result (impl/url-decode-coll %) path-params))]
|
||||
[(conj pl (-> (trie/insert nil p (->Match p data result nil nil)) (trie/compile)))
|
||||
[(conj pl (-> (trie/insert nil p (->Match p data result nil nil) opts) (trie/compile)))
|
||||
(if name (assoc nl name f) nl)]))
|
||||
[[] {}]
|
||||
compiled-routes)
|
||||
|
|
@ -175,6 +176,7 @@
|
|||
| key | description |
|
||||
| -----------------------------|-------------|
|
||||
| `:reitit.trie/trie-compiler` | Optional trie-compiler.
|
||||
| `:reitit.trie/parameters` | Optional function to transform path-parameters at creation time (default `identity`)."
|
||||
([compiled-routes]
|
||||
(trie-router compiled-routes {}))
|
||||
([compiled-routes opts]
|
||||
|
|
@ -186,7 +188,7 @@
|
|||
f #(if-let [path (impl/path-for route %)]
|
||||
(->Match p data result (impl/url-decode-coll %) path)
|
||||
(->PartialMatch p data result (impl/url-decode-coll %) path-params))]
|
||||
[(trie/insert pl p (->Match p data result nil nil))
|
||||
[(trie/insert pl p (->Match p data result nil nil) opts)
|
||||
(if name (assoc nl name f) nl)]))
|
||||
[nil {}]
|
||||
compiled-routes)
|
||||
|
|
|
|||
|
|
@ -288,6 +288,18 @@
|
|||
;; Managing Tries
|
||||
;;
|
||||
|
||||
#?(:clj
|
||||
(def record-parameters
|
||||
"Memoized function to transform parameters into runtime generated Record."
|
||||
(memoize
|
||||
(fn [params]
|
||||
(let [fields (keys params)]
|
||||
(if (some qualified-keyword? fields)
|
||||
params
|
||||
(let [name (gensym "PathParams")
|
||||
ctor (symbol (str "map->" name))]
|
||||
(eval `(do (defrecord ~name ~(mapv symbol fields)) (~ctor {}))))))))))
|
||||
|
||||
(defn insert
|
||||
"Returns a trie with routes added to it."
|
||||
([routes]
|
||||
|
|
@ -298,8 +310,10 @@
|
|||
(insert acc p d))
|
||||
node routes))
|
||||
([node path data]
|
||||
(insert node path data nil))
|
||||
([node path data {::keys [parameters] :or {parameters identity}}]
|
||||
(let [parts (split-path path)
|
||||
params (zipmap (->> parts (remove string?) (map :value)) (repeat nil))]
|
||||
params (parameters (zipmap (->> parts (remove string?) (map :value)) (repeat nil)))]
|
||||
(-insert (or node (-node {})) (split-path path) path params data))))
|
||||
|
||||
(defn compiler
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
(:require [criterium.core :as cc]
|
||||
[reitit.perf-utils :refer :all]
|
||||
[reitit.ring :as ring]
|
||||
[reitit.trie :as trie]
|
||||
[clojure.string :as str]))
|
||||
|
||||
;;
|
||||
|
|
@ -295,7 +296,8 @@
|
|||
(def app
|
||||
(ring/ring-handler
|
||||
(ring/router
|
||||
(reduce (partial add h) [] routes))
|
||||
(reduce (partial add h) [] routes)
|
||||
{::trie/parameters trie/record-parameters})
|
||||
(ring/create-default-handler)
|
||||
{:inject-match? false, :inject-router? false}))
|
||||
|
||||
|
|
@ -335,6 +337,7 @@
|
|||
;; 273ns (trie-router, no injects, direct-data)
|
||||
;; 256ns (trie-router, pre-defined parameters)
|
||||
;; 237ns (trie-router, single-sweep wild-params)
|
||||
;; 191ns (trie-router, record parameters)
|
||||
(let [req (map->Req {:request-method :get, :uri "/repos/julienschmidt/httprouter/stargazers"})]
|
||||
(title "param")
|
||||
(assert (= {:status 200, :body "/repos/:owner/:repo/stargazers"} (app req)))
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@
|
|||
(trie/compile
|
||||
(reduce
|
||||
(fn [acc [p d]]
|
||||
(trie/insert acc p d))
|
||||
(trie/insert acc p d {::trie/parameters trie/record-parameters}))
|
||||
nil routes))))
|
||||
|
||||
(defn bench! []
|
||||
|
|
@ -117,6 +117,7 @@
|
|||
;; 0.300µs (iterate arrays)
|
||||
;; 0.280µs (list-params)
|
||||
;; 0.096µs (trie)
|
||||
;; 0.083µs (trie, record-params, faster decode)
|
||||
(cc/with-progress-reporting
|
||||
(cc/bench
|
||||
(trie-matcher "/v1/orgs/1/topics"))))
|
||||
|
|
|
|||
|
|
@ -34,4 +34,11 @@
|
|||
(is (= (trie/->Match {} {:a 1})
|
||||
((-> (trie/insert nil "" {:a 1})
|
||||
(trie/compile)
|
||||
(trie/path-matcher)) ""))))
|
||||
(trie/path-matcher)) "")))
|
||||
|
||||
#?(:clj
|
||||
(let [match ((-> (trie/insert nil "/:a" {:a 1} {::trie/parameters trie/record-parameters})
|
||||
(trie/compile)
|
||||
(trie/path-matcher)) "/a")]
|
||||
(is (record? (:params match)))
|
||||
(is (= (trie/->Match {:a "a"} {:a 1}) (update match :params (partial into {})))))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue