diff --git a/CHANGELOG.md b/CHANGELOG.md index acfa86c7..22c439f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ * `"/file-:id/topics"` (free start, ends at slash) * `"/file-{name}.html"` (free start & end) * backed by a new `:trie-router`, replacing `:segment-router` - * [over 40% faster](https://metosin.github.io/reitit/performance.html) on the JVM + * [up to 2x faster](https://metosin.github.io/reitit/performance.html) on the JVM * **BREAKING**: `reitit.spec/validate-spec!` has been renamed to `validate` * With `clojure.spec` coercion, values flow through both `st/coerce` & `st/conform` yielding better error messages. Original issue in [compojure-api](https://github.com/metosin/compojure-api/issues/409). @@ -59,7 +59,7 @@ ### `reitit-frontend` -* **BREAKING**: Frontend controllers redesigned +* Frontend controllers redesigned * Controller `:params` function has been deprecated * Controller `:identity` function works the same as `:params` * New `:parameters` option can be used to declare which parameters diff --git a/modules/reitit-core/java-src/reitit/Trie.java b/modules/reitit-core/java-src/reitit/Trie.java index 65f98a42..953a70ad 100644 --- a/modules/reitit-core/java-src/reitit/Trie.java +++ b/modules/reitit-core/java-src/reitit/Trie.java @@ -160,10 +160,14 @@ public class Trie { @Override public Match match(int i, int max, char[] path) { + boolean hasPercent = false; + boolean hasPlus = false; if (i < max && path[i] != end) { int stop = max; for (int j = i; j < max; j++) { final char c = path[j]; + hasPercent = hasPercent || c == '%'; + hasPlus = hasPlus || c == '+'; if (c == end) { stop = j; break; @@ -171,7 +175,7 @@ public class Trie { } final Match m = child.match(stop, max, path); if (m != null) { - m.params = m.params.assoc(key, decode(path, i, stop)); + m.params = m.params.assoc(key, decode(new String(path, i, stop - i), hasPercent, hasPlus)); } return m; } diff --git a/perf-test/clj/reitit/go_perf_test.clj b/perf-test/clj/reitit/go_perf_test.clj index 59838449..176cde7c 100644 --- a/perf-test/clj/reitit/go_perf_test.clj +++ b/perf-test/clj/reitit/go_perf_test.clj @@ -334,6 +334,7 @@ ;; 277ns (trie-router, no injects, switch-case) - 690ns clojure ;; 273ns (trie-router, no injects, direct-data) ;; 256ns (trie-router, pre-defined parameters) + ;; 237ns (trie-router, single-sweep wild-params) (let [req (map->Req {:request-method :get, :uri "/repos/julienschmidt/httprouter/stargazers"})] (title "param") (assert (= {:status 200, :body "/repos/:owner/:repo/stargazers"} (app req))) @@ -365,6 +366,6 @@ (do (require '[clj-async-profiler.core :as prof]) (prof/profile - (dotimes [_ 1000000] + (dotimes [_ 10000000] (app {:request-method :get, :uri "/repos/julienschmidt/httprouter/stargazers"}))) (prof/serve-files 8080)))