PoC: Introduce FilePatternRouter
I've implemented another router! It is debatable whether it is appropriate to add even more new routers, but I think this router has enough characteristics to merit discussion.
What features does this router have?
This is a router for file-based routing. Performance tuning was done by reducing the number of routing format patterns supported.
- Less than 200 lines
- Fast initialization
- High performance
I haven't written a test yet, so it doesn't work properly, but it works on almost the same principle as RegExpRouter, so I think it will work if fixed bugs.
Benchmark
Nearly the same performance as RegExpRouter
% npm run bench:node
> bench:node
> tsx ./src/bench.mts
cpu: Apple M2 Pro
runtime: node v20.0.0 (arm64-darwin)
benchmark time (avg) (min … max) p75 p99 p995
---------------------------------------------------------------------------- -----------------------------
• short static - GET /user
---------------------------------------------------------------------------- -----------------------------
Hono RegExpRouter 58.91 ns/iter (51.05 ns … 136.05 ns) 60.52 ns 107.4 ns 111.47 ns
Hono TrieRouter 211.09 ns/iter (194.67 ns … 267.97 ns) 213.53 ns 252.62 ns 266.85 ns
Hono FilePatternRouter 79.3 ns/iter (69.47 ns … 502.8 ns) 80.72 ns 128.91 ns 132.31 ns
@medley/router 88.29 ns/iter (79.59 ns … 117.61 ns) 90.22 ns 101.7 ns 103.94 ns
find-my-way 80.37 ns/iter (71.42 ns … 106 ns) 83.82 ns 93.55 ns 95.64 ns
koa-tree-router 76 ns/iter (68.05 ns … 94.72 ns) 77.54 ns 87.96 ns 89.55 ns
trek-router 100.55 ns/iter (90.61 ns … 128.89 ns) 103.59 ns 116.5 ns 117.92 ns
express (WARNING: includes handling) 1.02 µs/iter (979.55 ns … 1.07 µs) 1.03 µs 1.07 µs 1.07 µs
koa-router 1.85 µs/iter (1.81 µs … 1.89 µs) 1.87 µs 1.89 µs 1.89 µs
radix3 80.45 ns/iter (72.74 ns … 98.29 ns) 81.12 ns 92.33 ns 95.23 ns
summary for short static - GET /user
Hono RegExpRouter
1.29x faster than koa-tree-router
1.35x faster than Hono FilePatternRouter
1.36x faster than find-my-way
1.37x faster than radix3
1.5x faster than @medley/router
1.71x faster than trek-router
3.58x faster than Hono TrieRouter
17.31x faster than express (WARNING: includes handling)
31.43x faster than koa-router
• static with same radix - GET /user/comments
---------------------------------------------------------------------------- -----------------------------
Hono RegExpRouter 66.06 ns/iter (59.44 ns … 82.79 ns) 67.34 ns 79.32 ns 79.89 ns
Hono TrieRouter 233.42 ns/iter (210.4 ns … 431.3 ns) 235.63 ns 260.6 ns 281.34 ns
Hono FilePatternRouter 86.94 ns/iter (78.55 ns … 141.28 ns) 88.44 ns 99.05 ns 107.49 ns
@medley/router 135.26 ns/iter (124.11 ns … 153.46 ns) 138.38 ns 148.45 ns 150.34 ns
find-my-way 147.39 ns/iter (133.8 ns … 222.41 ns) 151.96 ns 163.5 ns 176.84 ns
koa-tree-router 111.78 ns/iter (99.56 ns … 191.88 ns) 116.47 ns 138.41 ns 139.72 ns
trek-router 160.37 ns/iter (145.94 ns … 198.02 ns) 165.46 ns 191.18 ns 195.03 ns
express (WARNING: includes handling) 1.09 µs/iter (1.04 µs … 1.2 µs) 1.1 µs 1.2 µs 1.2 µs
koa-router 1.88 µs/iter (1.84 µs … 1.97 µs) 1.89 µs 1.97 µs 1.97 µs
radix3 86.57 ns/iter (77.52 ns … 130.18 ns) 88.57 ns 108.02 ns 114.7 ns
summary for static with same radix - GET /user/comments
Hono RegExpRouter
1.31x faster than radix3
1.32x faster than Hono FilePatternRouter
1.69x faster than koa-tree-router
2.05x faster than @medley/router
2.23x faster than find-my-way
2.43x faster than trek-router
3.53x faster than Hono TrieRouter
16.48x faster than express (WARNING: includes handling)
28.43x faster than koa-router
• dynamic route - GET /user/lookup/username/hey
---------------------------------------------------------------------------- -----------------------------
Hono RegExpRouter 136.29 ns/iter (122.33 ns … 166.61 ns) 141.5 ns 154.23 ns 164.02 ns
Hono TrieRouter 372.56 ns/iter (350.58 ns … 590.02 ns) 376.68 ns 433.76 ns 590.02 ns
Hono FilePatternRouter 88.5 ns/iter (80.05 ns … 113.7 ns) 90.63 ns 104.95 ns 110.15 ns
@medley/router 188.55 ns/iter (170.17 ns … 247.84 ns) 192.1 ns 217.18 ns 218.54 ns
find-my-way 223.37 ns/iter (202.89 ns … 277.1 ns) 228.78 ns 262.39 ns 265.58 ns
koa-tree-router 169.16 ns/iter (152.82 ns … 203.72 ns) 174.07 ns 193.65 ns 201.94 ns
trek-router 268.98 ns/iter (249.23 ns … 317.05 ns) 274.48 ns 307.78 ns 317.05 ns
express (WARNING: includes handling) 1.73 µs/iter (1.68 µs … 1.8 µs) 1.74 µs 1.8 µs 1.8 µs
koa-router 1.88 µs/iter (1.83 µs … 1.98 µs) 1.89 µs 1.98 µs 1.98 µs
radix3 395.96 ns/iter (372.88 ns … 478.81 ns) 402.25 ns 434.68 ns 478.81 ns
summary for dynamic route - GET /user/lookup/username/hey
Hono FilePatternRouter
1.54x faster than Hono RegExpRouter
1.91x faster than koa-tree-router
2.13x faster than @medley/router
2.52x faster than find-my-way
3.04x faster than trek-router
4.21x faster than Hono TrieRouter
4.47x faster than radix3
19.53x faster than express (WARNING: includes handling)
21.24x faster than koa-router
• mixed static dynamic - GET /event/abcd1234/comments
---------------------------------------------------------------------------- -----------------------------
Hono RegExpRouter 137.81 ns/iter (120.05 ns … 282 ns) 140.41 ns 246.46 ns 268.75 ns
Hono TrieRouter 410.34 ns/iter (377.88 ns … 765.28 ns) 411.47 ns 509.07 ns 765.28 ns
Hono FilePatternRouter 86.65 ns/iter (77.3 ns … 115.13 ns) 88.2 ns 102.59 ns 108.73 ns
@medley/router 156.36 ns/iter (144.2 ns … 390.76 ns) 159.08 ns 182.5 ns 291.98 ns
find-my-way 200.26 ns/iter (179.33 ns … 581.04 ns) 203.52 ns 274.63 ns 392.51 ns
koa-tree-router 141.91 ns/iter (128.65 ns … 168.74 ns) 147.58 ns 162.32 ns 166.07 ns
trek-router 230.61 ns/iter (215.44 ns … 280.25 ns) 236.32 ns 264.18 ns 266.87 ns
express (WARNING: includes handling) 1.89 µs/iter (1.81 µs … 2.16 µs) 1.91 µs 2.16 µs 2.16 µs
koa-router 1.93 µs/iter (1.85 µs … 2.44 µs) 1.93 µs 2.44 µs 2.44 µs
radix3 376.95 ns/iter (352.57 ns … 454.3 ns) 384.84 ns 402.63 ns 454.3 ns
summary for mixed static dynamic - GET /event/abcd1234/comments
Hono FilePatternRouter
1.59x faster than Hono RegExpRouter
1.64x faster than koa-tree-router
1.8x faster than @medley/router
2.31x faster than find-my-way
2.66x faster than trek-router
4.35x faster than radix3
4.74x faster than Hono TrieRouter
21.86x faster than express (WARNING: includes handling)
22.26x faster than koa-router
• post - POST /event/abcd1234/comment
---------------------------------------------------------------------------- -----------------------------
Hono RegExpRouter 122.76 ns/iter (111.57 ns … 154.22 ns) 127.59 ns 145.9 ns 147.73 ns
Hono TrieRouter 435.07 ns/iter (394.88 ns … 979.27 ns) 427.49 ns 777.25 ns 979.27 ns
Hono FilePatternRouter 138.52 ns/iter (124.78 ns … 260.35 ns) 142 ns 175.8 ns 194.97 ns
@medley/router 149.17 ns/iter (139.13 ns … 343.57 ns) 152.33 ns 172.1 ns 186.98 ns
find-my-way 203.02 ns/iter (182.47 ns … 747.03 ns) 202.47 ns 515.17 ns 565.67 ns
koa-tree-router 135.33 ns/iter (118.64 ns … 718.98 ns) 137.77 ns 178.27 ns 427.55 ns
trek-router 192.5 ns/iter (178.58 ns … 226.7 ns) 198.45 ns 219.69 ns 225.13 ns
express (WARNING: includes handling) 1.9 µs/iter (1.86 µs … 1.97 µs) 1.91 µs 1.97 µs 1.97 µs
koa-router 1.91 µs/iter (1.84 µs … 2.58 µs) 1.9 µs 2.58 µs 2.58 µs
radix3 375.8 ns/iter (353.62 ns … 458.61 ns) 381 ns 409.31 ns 458.61 ns
summary for post - POST /event/abcd1234/comment
Hono RegExpRouter
1.1x faster than koa-tree-router
1.13x faster than Hono FilePatternRouter
1.22x faster than @medley/router
1.57x faster than trek-router
1.65x faster than find-my-way
3.06x faster than radix3
3.54x faster than Hono TrieRouter
15.45x faster than express (WARNING: includes handling)
15.59x faster than koa-router
• long static - GET /very/deeply/nested/route/hello/there
---------------------------------------------------------------------------- -----------------------------
Hono RegExpRouter 77.67 ns/iter (66.17 ns … 1.05 µs) 75.78 ns 94.41 ns 97.32 ns
Hono TrieRouter 334.03 ns/iter (305.36 ns … 922.28 ns) 338.85 ns 365.54 ns 922.28 ns
Hono FilePatternRouter 96.46 ns/iter (85.35 ns … 1.12 µs) 94.96 ns 124.45 ns 180.41 ns
@medley/router 119.39 ns/iter (105.41 ns … 1 µs) 116.87 ns 144.58 ns 685.12 ns
find-my-way 197.86 ns/iter (183.28 ns … 230.28 ns) 203.15 ns 224.45 ns 229.51 ns
koa-tree-router 115.76 ns/iter (104.94 ns … 951.02 ns) 117.1 ns 152.61 ns 180.44 ns
trek-router 132.37 ns/iter (122.87 ns … 186.36 ns) 135.83 ns 153.37 ns 161.32 ns
express (WARNING: includes handling) 1.37 µs/iter (1.31 µs … 1.57 µs) 1.38 µs 1.57 µs 1.57 µs
koa-router 1.99 µs/iter (1.82 µs … 2.93 µs) 2.01 µs 2.93 µs 2.93 µs
radix3 87.67 ns/iter (78.33 ns … 929.75 ns) 87.28 ns 103.88 ns 112.37 ns
summary for long static - GET /very/deeply/nested/route/hello/there
Hono RegExpRouter
1.13x faster than radix3
1.24x faster than Hono FilePatternRouter
1.49x faster than koa-tree-router
1.54x faster than @medley/router
1.7x faster than trek-router
2.55x faster than find-my-way
4.3x faster than Hono TrieRouter
17.67x faster than express (WARNING: includes handling)
25.6x faster than koa-router
• wildcard - GET /static/index.html
---------------------------------------------------------------------------- -----------------------------
Hono RegExpRouter 135.81 ns/iter (124.22 ns … 177.29 ns) 139.88 ns 165.33 ns 171.44 ns
Hono TrieRouter 289.58 ns/iter (259.91 ns … 1.35 µs) 281.46 ns 745.39 ns 1.35 µs
Hono FilePatternRouter 124.07 ns/iter (114.05 ns … 167.81 ns) 128.47 ns 142.99 ns 146.57 ns
@medley/router 109.92 ns/iter (97.46 ns … 255.35 ns) 111.77 ns 125.27 ns 126.26 ns
find-my-way 170.38 ns/iter (157.22 ns … 216.25 ns) 175.78 ns 204.81 ns 209.27 ns
koa-tree-router 143.54 ns/iter (131.88 ns … 171.5 ns) 147.97 ns 163.4 ns 165.68 ns
trek-router 171.31 ns/iter (158.74 ns … 208.93 ns) 176.14 ns 198.67 ns 208.67 ns
express (WARNING: includes handling) 2.11 µs/iter (2.01 µs … 3.05 µs) 2.11 µs 3.05 µs 3.05 µs
koa-router 1.9 µs/iter (1.81 µs … 2.48 µs) 1.88 µs 2.48 µs 2.48 µs
radix3 371.09 ns/iter (348.55 ns … 451.24 ns) 375.56 ns 438.87 ns 451.24 ns
summary for wildcard - GET /static/index.html
@medley/router
1.13x faster than Hono FilePatternRouter
1.24x faster than Hono RegExpRouter
1.31x faster than koa-tree-router
1.55x faster than find-my-way
1.56x faster than trek-router
2.63x faster than Hono TrieRouter
3.38x faster than radix3
17.25x faster than koa-router
19.15x faster than express (WARNING: includes handling)
• all together
---------------------------------------------------------------------------- -----------------------------
Hono RegExpRouter 397.98 ns/iter (369.44 ns … 1.08 µs) 398.2 ns 540.96 ns 1.08 µs
Hono TrieRouter 2.02 µs/iter (1.9 µs … 3 µs) 2 µs 3 µs 3 µs
Hono FilePatternRouter 443.1 ns/iter (399.37 ns … 1.71 µs) 435.84 ns 921.95 ns 1.71 µs
@medley/router 665.74 ns/iter (610.99 ns … 1.69 µs) 650.15 ns 1.69 µs 1.69 µs
find-my-way 1.08 µs/iter (994.02 ns … 2.33 µs) 1.05 µs 2.33 µs 2.33 µs
koa-tree-router 611.28 ns/iter (578.8 ns … 997.83 ns) 616.11 ns 997.83 ns 997.83 ns
trek-router 976.31 ns/iter (921.32 ns … 1.35 µs) 982.9 ns 1.35 µs 1.35 µs
express (WARNING: includes handling) 11.32 µs/iter (9.92 µs … 7.32 ms) 10.83 µs 14.5 µs 15.67 µs
koa-router 12.99 µs/iter (11.63 µs … 2.17 ms) 12.63 µs 16.71 µs 24.21 µs
radix3 1.61 µs/iter (1.47 µs … 2.96 µs) 1.55 µs 2.96 µs 2.96 µs
summary for all together
Hono RegExpRouter
1.11x faster than Hono FilePatternRouter
1.54x faster than koa-tree-router
1.67x faster than @medley/router
2.45x faster than trek-router
2.71x faster than find-my-way
4.03x faster than radix3
5.08x faster than Hono TrieRouter
28.46x faster than express (WARNING: includes handling)
32.63x faster than koa-router
Initialization performance is not as good as LinearRouter, but fast enough.
% npm run bench-includes-init:node
> bench-includes-init:node
> tsx ./src/bench-includes-init.mts
cpu: Apple M2 Pro
runtime: node v20.0.0 (arm64-darwin)
benchmark time (avg) (min … max) p75 p99 p995
--------------------------------------------------------- -----------------------------
• GET /user
--------------------------------------------------------- -----------------------------
RegExpRouter 35.77 µs/iter (26.21 µs … 15.11 ms) 31.42 µs 69.54 µs 375.42 µs
TrieRouter 5.76 µs/iter (4.92 µs … 268.75 µs) 5.58 µs 7 µs 8.75 µs
LinearRouter 958.76 ns/iter (916.41 ns … 989.93 ns) 969.11 ns 989.93 ns 989.93 ns
FilePatternRouter 2.86 µs/iter (2.81 µs … 2.91 µs) 2.87 µs 2.91 µs 2.91 µs
MedleyRouter 2.86 µs/iter (2.81 µs … 2.93 µs) 2.87 µs 2.93 µs 2.93 µs
FindMyWay 89.77 µs/iter (78.21 µs … 4.13 ms) 87.25 µs 160.25 µs 275.46 µs
KoaTreeRouter 2.1 µs/iter (2.07 µs … 2.17 µs) 2.11 µs 2.17 µs 2.17 µs
TrekRouter 2.93 µs/iter (2.87 µs … 3.07 µs) 2.94 µs 3.07 µs 3.07 µs
summary for GET /user
LinearRouter
2.19x faster than KoaTreeRouter
2.98x faster than FilePatternRouter
2.98x faster than MedleyRouter
3.06x faster than TrekRouter
6x faster than TrieRouter
37.31x faster than RegExpRouter
93.63x faster than FindMyWay
• GET /user/comments
--------------------------------------------------------- -----------------------------
RegExpRouter 36.52 µs/iter (25.96 µs … 2.29 ms) 30.46 µs 230.38 µs 473.71 µs
TrieRouter 5.75 µs/iter (5.68 µs … 5.9 µs) 5.76 µs 5.9 µs 5.9 µs
LinearRouter 1.05 µs/iter (1.02 µs … 1.08 µs) 1.06 µs 1.08 µs 1.08 µs
FilePatternRouter 2.89 µs/iter (2.82 µs … 2.95 µs) 2.92 µs 2.95 µs 2.95 µs
MedleyRouter 2.94 µs/iter (2.89 µs … 3.06 µs) 2.96 µs 3.06 µs 3.06 µs
FindMyWay 93.93 µs/iter (78.21 µs … 3.08 ms) 88.21 µs 280.21 µs 360.71 µs
KoaTreeRouter 2.16 µs/iter (2.12 µs … 2.21 µs) 2.17 µs 2.21 µs 2.21 µs
TrekRouter 3 µs/iter (2.93 µs … 3.1 µs) 3.04 µs 3.1 µs 3.1 µs
summary for GET /user/comments
LinearRouter
2.05x faster than KoaTreeRouter
2.74x faster than FilePatternRouter
2.8x faster than MedleyRouter
2.86x faster than TrekRouter
5.46x faster than TrieRouter
34.73x faster than RegExpRouter
89.32x faster than FindMyWay
• GET /user/lookup/username/hey
--------------------------------------------------------- -----------------------------
RegExpRouter 51.61 µs/iter (26.17 µs … 9.83 ms) 31.13 µs 591.08 µs 1.15 ms
TrieRouter 5.98 µs/iter (5.91 µs … 6.06 µs) 6.01 µs 6.06 µs 6.06 µs
LinearRouter 1.22 µs/iter (1.18 µs … 1.28 µs) 1.23 µs 1.28 µs 1.28 µs
FilePatternRouter 2.96 µs/iter (2.89 µs … 3.18 µs) 2.99 µs 3.18 µs 3.18 µs
MedleyRouter 3.02 µs/iter (2.96 µs … 3.08 µs) 3.05 µs 3.08 µs 3.08 µs
FindMyWay 97.06 µs/iter (80.46 µs … 3.59 ms) 89.46 µs 291.63 µs 372.83 µs
KoaTreeRouter 2.28 µs/iter (2.18 µs … 2.67 µs) 2.3 µs 2.67 µs 2.67 µs
TrekRouter 3.11 µs/iter (3.06 µs … 3.16 µs) 3.13 µs 3.16 µs 3.16 µs
summary for GET /user/lookup/username/hey
LinearRouter
1.87x faster than KoaTreeRouter
2.43x faster than FilePatternRouter
2.48x faster than MedleyRouter
2.55x faster than TrekRouter
4.9x faster than TrieRouter
42.3x faster than RegExpRouter
79.56x faster than FindMyWay
• GET /event/abcd1234/comments
--------------------------------------------------------- -----------------------------
RegExpRouter 51.52 µs/iter (26.13 µs … 5.8 ms) 30.79 µs 542.96 µs 1.13 ms
TrieRouter 6.05 µs/iter (5.94 µs … 6.39 µs) 6.11 µs 6.39 µs 6.39 µs
LinearRouter 1.24 µs/iter (1.2 µs … 1.55 µs) 1.24 µs 1.55 µs 1.55 µs
FilePatternRouter 2.96 µs/iter (2.88 µs … 3.48 µs) 2.97 µs 3.48 µs 3.48 µs
MedleyRouter 2.96 µs/iter (2.93 µs … 3.02 µs) 2.98 µs 3.02 µs 3.02 µs
FindMyWay 92.96 µs/iter (79.04 µs … 4.78 ms) 86.96 µs 255.75 µs 356.83 µs
KoaTreeRouter 2.19 µs/iter (2.14 µs … 2.24 µs) 2.2 µs 2.24 µs 2.24 µs
TrekRouter 3.09 µs/iter (3.04 µs … 3.18 µs) 3.11 µs 3.18 µs 3.18 µs
summary for GET /event/abcd1234/comments
LinearRouter
1.77x faster than KoaTreeRouter
2.39x faster than FilePatternRouter
2.4x faster than MedleyRouter
2.5x faster than TrekRouter
4.9x faster than TrieRouter
41.66x faster than RegExpRouter
75.17x faster than FindMyWay
• POST /event/abcd1234/comment
--------------------------------------------------------- -----------------------------
RegExpRouter 55.51 µs/iter (26.08 µs … 9.95 ms) 31.13 µs 562.63 µs 1.13 ms
TrieRouter 6.08 µs/iter (5.89 µs … 6.7 µs) 6.06 µs 6.7 µs 6.7 µs
LinearRouter 384.92 ns/iter (360.12 ns … 456.6 ns) 390.7 ns 447.47 ns 456.6 ns
FilePatternRouter 3.1 µs/iter (2.86 µs … 3.92 µs) 3.13 µs 3.92 µs 3.92 µs
MedleyRouter 3 µs/iter (2.91 µs … 3.18 µs) 3.03 µs 3.18 µs 3.18 µs
FindMyWay 99.26 µs/iter (80.08 µs … 9.37 ms) 87.71 µs 258.08 µs 368.63 µs
KoaTreeRouter 2.23 µs/iter (2.13 µs … 2.98 µs) 2.2 µs 2.98 µs 2.98 µs
TrekRouter 3.08 µs/iter (3 µs … 3.21 µs) 3.11 µs 3.21 µs 3.21 µs
summary for POST /event/abcd1234/comment
LinearRouter
5.8x faster than KoaTreeRouter
7.81x faster than MedleyRouter
7.99x faster than TrekRouter
8.06x faster than FilePatternRouter
15.8x faster than TrieRouter
144.21x faster than RegExpRouter
257.86x faster than FindMyWay
• GET /very/deeply/nested/route/hello/there
--------------------------------------------------------- -----------------------------
RegExpRouter 70.84 µs/iter (26.33 µs … 12.93 ms) 31.08 µs 728.38 µs 1.45 ms
TrieRouter 5.96 µs/iter (5.84 µs … 6.11 µs) 6.01 µs 6.11 µs 6.11 µs
LinearRouter 1.24 µs/iter (1.16 µs … 1.71 µs) 1.25 µs 1.71 µs 1.71 µs
FilePatternRouter 3.03 µs/iter (2.88 µs … 3.71 µs) 3.02 µs 3.71 µs 3.71 µs
MedleyRouter 3.05 µs/iter (2.83 µs … 3.63 µs) 3.01 µs 3.63 µs 3.63 µs
FindMyWay 104.42 µs/iter (79.21 µs … 12.81 ms) 86.88 µs 270.83 µs 451.88 µs
KoaTreeRouter 2.18 µs/iter (2.11 µs … 2.39 µs) 2.18 µs 2.39 µs 2.39 µs
TrekRouter 2.99 µs/iter (2.91 µs … 3.13 µs) 3.01 µs 3.13 µs 3.13 µs
summary for GET /very/deeply/nested/route/hello/there
LinearRouter
1.75x faster than KoaTreeRouter
2.41x faster than TrekRouter
2.44x faster than FilePatternRouter
2.45x faster than MedleyRouter
4.8x faster than TrieRouter
57.09x faster than RegExpRouter
84.14x faster than FindMyWay
• GET /static/index.html
--------------------------------------------------------- -----------------------------
RegExpRouter 79.11 µs/iter (26.21 µs … 14.95 ms) 31 µs 721.13 µs 1.67 ms
TrieRouter 6.37 µs/iter (5 µs … 14.3 ms) 5.71 µs 9.63 µs 14.92 µs
LinearRouter 1.06 µs/iter (998.48 ns … 2.12 µs) 1.06 µs 2.12 µs 2.12 µs
FilePatternRouter 2.96 µs/iter (2.81 µs … 3.74 µs) 2.99 µs 3.74 µs 3.74 µs
MedleyRouter 2.89 µs/iter (2.77 µs … 3.14 µs) 2.9 µs 3.14 µs 3.14 µs
FindMyWay 102.3 µs/iter (79.92 µs … 10.84 ms) 86.46 µs 204.29 µs 328.42 µs
KoaTreeRouter 2.19 µs/iter (2.13 µs … 2.33 µs) 2.21 µs 2.33 µs 2.33 µs
TrekRouter 3.02 µs/iter (2.93 µs … 3.13 µs) 3.04 µs 3.13 µs 3.13 µs
summary for GET /static/index.html
LinearRouter
2.06x faster than KoaTreeRouter
2.72x faster than MedleyRouter
2.79x faster than FilePatternRouter
2.84x faster than TrekRouter
6x faster than TrieRouter
74.47x faster than RegExpRouter
96.3x faster than FindMyWay
The bundle size of the application created with sonik on my environment was reduced as follows
71.27 kB -> 56.25 kB
Author should do the followings, if applicable
- [ ] Add tests
- [ ] Run tests
- [ ]
yarn denoifyto generate files for Deno
@yusukebe How about a router like this?
Added basic tests by 8270f04
Now the performance of initialization is degrading.
% npm run bench-includes-init:node
....
LinearRouter
2.11x faster than KoaTreeRouter
2.88x faster than MedleyRouter
2.91x faster than TrekRouter
5.28x faster than FilePatternRouter
5.75x faster than TrieRouter
75.12x faster than RegExpRouter
89.9x faster than FindMyWay
Hi @usualoma !
To ensure I understand correctly, I want to know the advantages of using FilePatternRouter for file-based routing. I think marking /foo/* as isMiddleware is a key point.
Btw, I'm currently working on changing the API of Sonik to make it simpler by using Hono's core features.
https://github.com/sonikjs/sonik/pull/16
6e504c7 changes made it a little faster.
% npm run bench-includes-init:node
....
summary for GET /static/index.html
LinearRouter
2.13x faster than KoaTreeRouter
2.79x faster than MedleyRouter
2.89x faster than TrekRouter
4.7x faster than FilePatternRouter
5.62x faster than TrieRouter
80.25x faster than RegExpRouter
115.14x faster than FindMyWa
@yusukebe Sorry, I will explain the specifications.
Supported Path Patterns
- Static path
/path/to/static
- Capture parameter
/posts/:id,/posts/:id/comments
- Middleware
*,/*,/posts/*,posts/:id/*
The following are not supported
/wild/*/card/post/:date{[0-9]+}/:title{[a-z]+}/api/animals/:type?/js/:filename{[a-z0-9/]+.js}
Other Restrictions
- Maximum path length is 99 characters (but can be changed)
There are no other restrictions and FilePatternRouter can be used just like any other router.
At 41bbe94
Less than 200 lines-> About 200 linesFast initialization-> Not slow initialization- High performance
- Even with the addition of tons of middleware, performance will not be degraded.
Hi @usualoma,
Thank you for explaining the details. I fully understand now.
It's great to have a router specialized for file-based routing. As you mentioned, the patterns used in file-based routing are fewer than in normal Hono usage.
Currently, for my plan to release the file-based routing feature, I'm not sure if it will be Sonik, separate from this Hono repo, or another framework structure, but it will be released as v4. So, I think we should consider including this FilePatternRouter in v4. Until then, how about we keep this open?
I agree 👍
I think we should consider including this FilePatternRouter in v4. Until then, how about we keep this open?
Sorry, I submitted once to #1850 by mistake.
Cons
I did not mention the cons of this router, so I will add them here.
The regex generated is large
The RegExpRouter compiled the regexes to be as small as possible, but the FilePatternRouter does not make that effort, so they become large for many routing registrations.
For example
app.get('/users/:id', handlerA)app.get('/users/:id/posts', handlerB)app.get('/users/:id/posts/:post_id', handlerC)
RegExpRouter: /users/([^/]+)(? :()|(? :/posts(? :()|/([^/]+)()))
FilePatternRouter: /users/([^/]+)/posts/([^/]+)()||/users/([^/]+)/posts()||/users/([^/]+)())
The current implementation is a PoC, so no effort has been made to make it smaller, but I think it could be made smaller by adding a few lines and allowing for a little overhead. Additional implementation would be necessary depending on the number of routings envisioned.
@usualoma that's exciting!
I'm wondering how you can address a proper doc page with examples and tips on how to organize code. Would you be able to provide some examples on this PR?
I've used routing-controllers in the past which uses fancy Decorators, but they are not the same.
よくやった 🚀