ifs -> switch. maybe faster?

This commit is contained in:
Tommi Reiman 2019-02-05 08:51:21 +02:00
parent 2eb4513447
commit 5b9f90d283
2 changed files with 30 additions and 20 deletions

View file

@ -28,11 +28,15 @@ public class Trie {
boolean hasPercent = false; boolean hasPercent = false;
boolean hasPlus = false; boolean hasPlus = false;
for (int j = begin; j < end; j++) { for (int j = begin; j < end; j++) {
final char c = chars[j]; switch (chars[j]) {
if (c == '%') { case '%':
hasPercent = true; hasPercent = true;
} else if (c == '+') { break;
hasPlus = true; case '+':
hasPlus = true;
break;
default:
break;
} }
} }
return decode(chars, begin, end, hasPercent, hasPlus); return decode(chars, begin, end, hasPercent, hasPlus);
@ -151,16 +155,21 @@ public class Trie {
boolean hasPlus = false; boolean hasPlus = false;
for (int j = i; j < max; j++) { for (int j = i; j < max; j++) {
final char c = path[j]; final char c = path[j];
if (c == '/') { switch (c) {
final Match m = child.match(j, max, path, match); case '/':
if (m != null) { final Match m = child.match(j, max, path, match);
m.params.assoc(key, decode(path, i, j, hasPercent, hasPlus)); if (m != null) {
} m.params.assoc(key, decode(path, i, j, hasPercent, hasPlus));
return m; }
} else if (c == '%') { return m;
hasPercent = true; case '%':
} else if (c == '+') { hasPercent = true;
hasPlus = true; break;
case '+':
hasPlus = true;
break;
default:
break;
} }
} }
final Match m = child.match(max, max, path, match); final Match m = child.match(max, max, path, match);

View file

@ -330,7 +330,8 @@
;; 490ns (java-segment-router, no injects) ;; 490ns (java-segment-router, no injects)
;; 440ns (java-segment-router, no injects, single-wild-optimization) ;; 440ns (java-segment-router, no injects, single-wild-optimization)
;; 305ns (trie-router, no injects) ;; 305ns (trie-router, no injects)
;; 281ns (trie-router, no injects, optimized) - 690ns (clojure) ;; 281ns (trie-router, no injects, optimized)
;; 277ns (trie-router, no injects, switch-case) - 690ns clojure
(let [req (map->Req {:request-method :get, :uri "/repos/julienschmidt/httprouter/stargazers"})] (let [req (map->Req {:request-method :get, :uri "/repos/julienschmidt/httprouter/stargazers"})]
(title "param") (title "param")
(assert (= {:status 200, :body "/repos/:owner/:repo/stargazers"} (app req))) (assert (= {:status 200, :body "/repos/:owner/:repo/stargazers"} (app req)))
@ -344,6 +345,7 @@
;; 90µs (java-segment-router, no injects, single-wild-optimization) ;; 90µs (java-segment-router, no injects, single-wild-optimization)
;; 66µs (trie-router, no injects) ;; 66µs (trie-router, no injects)
;; 64µs (trie-router, no injects, optimized) - 124µs (clojure) ;; 64µs (trie-router, no injects, optimized) - 124µs (clojure)
;; 63µs (trie-router, no injects, switch-case) - 124µs (clojure)
(let [requests (mapv route->req routes)] (let [requests (mapv route->req routes)]
(title "all") (title "all")
(cc/quick-bench (cc/quick-bench
@ -357,8 +359,7 @@
(app {:request-method :get, :uri "/repos/julienschmidt/httprouter/stargazers"}) (app {:request-method :get, :uri "/repos/julienschmidt/httprouter/stargazers"})
(do (do
(require '[clj-async-profiler.core :as prof]) (require '[clj-async-profiler.core :as prof])
(prof/start {}) (prof/profile
(time (dotimes [_ 1000000]
(dotimes [_ 10000000]
(app {:request-method :get, :uri "/repos/julienschmidt/httprouter/stargazers"}))) (app {:request-method :get, :uri "/repos/julienschmidt/httprouter/stargazers"})))
(str (prof/stop {})))) (prof/serve-files 8080)))