├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── bench_test.go ├── conf └── app.conf ├── github_test.go ├── go.mod ├── go.sum ├── gplus_test.go ├── parse_test.go ├── routers.go ├── routers_test.go └── static_test.go /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.prof 3 | *.res 4 | *.test 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: go 3 | go: 4 | - 1.13.x 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2013, Julien Schmidt 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Go HTTP Router Benchmark 2 | ======================== 3 | 4 | This benchmark suite aims to compare the performance of HTTP request routers for [Go](https://golang.org) by implementing the routing structure of some real world APIs. 5 | Some of the APIs are slightly adapted, since they can not be implemented 1:1 in some of the routers. 6 | 7 | Of course the tested routers can be used for any kind of HTTP request → handler function routing, not only (REST) APIs. 8 | 9 | 10 | #### Tested routers & frameworks: 11 | 12 | * [Beego](http://beego.me/) 13 | * [go-json-rest](https://github.com/ant0ine/go-json-rest) 14 | * [Denco](https://github.com/naoina/denco) 15 | * [Gocraft Web](https://github.com/gocraft/web) 16 | * [Goji](https://github.com/zenazn/goji/) 17 | * [Gorilla Mux](http://www.gorillatoolkit.org/pkg/mux) 18 | * [http.ServeMux](http://golang.org/pkg/net/http/#ServeMux) 19 | * [HttpRouter](https://github.com/julienschmidt/httprouter) 20 | * [HttpTreeMux](https://github.com/dimfeld/httptreemux) 21 | * [Kocha-urlrouter](https://github.com/naoina/kocha-urlrouter) 22 | * [Martini](https://github.com/go-martini/martini) 23 | * [Pat](https://github.com/bmizerany/pat) 24 | * [Possum](https://github.com/mikespook/possum) 25 | * [R2router](https://github.com/vanng822/r2router) 26 | * [TigerTonic](https://github.com/rcrowley/go-tigertonic) 27 | * [Traffic](https://github.com/pilu/traffic) 28 | 29 | 30 | ## Motivation 31 | 32 | Go is a great language for web applications. Since the [default *request multiplexer*](http://golang.org/pkg/net/http/#ServeMux) of Go's net/http package is very simple and limited, an accordingly high number of HTTP request routers exist. 33 | 34 | Unfortunately, most of the (early) routers use pretty bad routing algorithms. Moreover, many of them are very wasteful with memory allocations, which can become a problem in a language with Garbage Collection like Go, since every (heap) allocation results in more work for the Garbage Collector. 35 | 36 | Lately more and more bloated frameworks pop up, outdoing one another in the number of features. This benchmark tries to measure their overhead. 37 | 38 | Be aware that we are comparing apples and oranges here. We compare feature-rich frameworks to packages with simple routing functionality only. But since we are only interested in decent request routing, I think this is not entirely unfair. The frameworks are configured to do as little additional work as possible. 39 | 40 | If you care about performance, this benchmark can maybe help you find the right router, which scales with your application. 41 | 42 | Personally, I prefer slim and optimized software, which is why I implemented [HttpRouter](https://github.com/julienschmidt/httprouter), which is also tested here. In fact, this benchmark suite started as part of the packages tests, but was then extended to a generic benchmark suite. 43 | So keep in mind, that I am not completely unbiased :relieved: 44 | 45 | 46 | ## Results 47 | 48 | Benchmark System: 49 | * Intel Core i5-2500K (4x 3,30GHz + Turbo Boost), CPU-governor: performance 50 | * 2x 4 GiB DDR3-1333 RAM, dual-channel 51 | * go version go1.3rc1 linux/amd64 52 | * Ubuntu 14.04 amd64 (Linux Kernel 3.13.0-29), fresh installation 53 | 54 | 55 | ### Memory Consumption 56 | 57 | Besides the micro-benchmarks, there are 3 sets of benchmarks where we play around with clones of some real-world APIs, and one benchmark with static routes only, to allow a comparison with [http.ServeMux](http://golang.org/pkg/net/http/#ServeMux). 58 | The following table shows the memory required only for loading the routing structure for the respective API. 59 | The best 3 values for each test are bold. I'm pretty sure you can detect a pattern :wink: 60 | 61 | | Router | Static | GitHub | Google+ | Parse | 62 | |:-------------|----------:|-----------:|----------:|----------:| 63 | | HttpServeMux |__18064 B__| - | - | - | 64 | | Beego | 79472 B | 497248 B | 26480 B | 38768 B | 65 | | Denco | 44752 B | 107632 B | 54896 B | 36368 B | 66 | | Gocraft Web | 57976 B | 95736 B | 8024 B | 13120 B | 67 | | Goji | 32400 B | __58424 B__| __3392 B__| __6704 B__| 68 | | Go-Json-Rest | 152608 B | 148352 B | 11696 B | 13712 B | 69 | | Gorilla Mux | 685152 B | 1557216 B | 80240 B | 125480 B | 70 | | HttpRouter |__26232 B__| __44344 B__| __3144 B__| __5792 B__| 71 | | HttpTreeMux | 75624 B | 81408 B | 7712 B | 7616 B | 72 | | Kocha | 130336 B | 811744 B | 139968 B | 191632 B | 73 | | Martini | 312592 B | 579472 B | 27520 B | 50608 B | 74 | | Pat |__21272 B__| __18968 B__| __1448 B__| __2360 B__| 75 | | TigerTonic | 85264 B | 99392 B | 10576 B | 11008 B | 76 | | Traffic | 649568 B | 1124704 B | 57984 B | 98168 B | 77 | 78 | The first place goes to [Pat](https://github.com/bmizerany/pat), followed by [HttpRouter](https://github.com/julienschmidt/httprouter) and [Goji](https://github.com/zenazn/goji/). Now, before everyone starts reading the documentation of Pat, `[SPOILER]` this low memory consumption comes at the price of relatively bad routing performance. The routing structure of Pat is simple - probably too simple. `[/SPOILER]`. 79 | 80 | Moreover main memory is cheap and usually not a scarce resource. As long as the router doesn't require Megabytes of memory, it should be no deal breaker. But it gives us a first hint how efficient or wasteful a router works. 81 | 82 | 83 | ### Static Routes 84 | 85 | The `Static` benchmark is not really a clone of a real-world API. It is just a collection of random static paths inspired by the structure of the Go directory. It might not be a realistic URL-structure. 86 | 87 | The only intention of this benchmark is to allow a comparison with the default router of Go's net/http package, [http.ServeMux](http://golang.org/pkg/net/http/#ServeMux), which is limited to static routes and does not support parameters in the route pattern. 88 | 89 | In the `StaticAll` benchmark each of 157 URLs is called once per repetition (op, *operation*). If you are unfamiliar with the `go test -bench` tool, the first number is the number of repetitions the `go test` tool made, to get a test running long enough for measurements. The second column shows the time in nanoseconds that a single repetition takes. The third number is the amount of heap memory allocated in bytes, the last one the average number of allocations made per repetition. 90 | 91 | The logs below show, that http.ServeMux has only medium performance, compared to more feature-rich routers. The fastest router only needs 1.8% of the time http.ServeMux needs. 92 | 93 | [HttpRouter](https://github.com/julienschmidt/httprouter) was the first router (I know of) that managed to serve all the static URLs without a single heap allocation. Since [the first run of this benchmark](https://github.com/julienschmidt/go-http-routing-benchmark/blob/0eb78904be13aee7a1e9f8943386f7c26b9d9d79/README.md) more routers followed this trend and were optimized in the same way. 94 | 95 | ``` 96 | BenchmarkHttpServeMux_StaticAll 5000 706222 ns/op 96 B/op 6 allocs/op 97 | 98 | BenchmarkBeego_StaticAll 2000 1408954 ns/op 482433 B/op 14088 allocs/op 99 | BenchmarkDenco_StaticAll 200000 12679 ns/op 0 B/op 0 allocs/op 100 | BenchmarkGocraftWeb_StaticAll 10000 154142 ns/op 51468 B/op 947 allocs/op 101 | BenchmarkGoji_StaticAll 20000 80518 ns/op 0 B/op 0 allocs/op 102 | BenchmarkGoJsonRest_StaticAll 2000 978164 ns/op 180973 B/op 3945 allocs/op 103 | BenchmarkGorillaMux_StaticAll 1000 1763690 ns/op 71804 B/op 956 allocs/op 104 | BenchmarkHttpRouter_StaticAll 100000 15010 ns/op 0 B/op 0 allocs/op 105 | BenchmarkHttpTreeMux_StaticAll 100000 15123 ns/op 0 B/op 0 allocs/op 106 | BenchmarkKocha_StaticAll 100000 23093 ns/op 0 B/op 0 allocs/op 107 | BenchmarkMartini_StaticAll 500 3444278 ns/op 156015 B/op 2351 allocs/op 108 | BenchmarkPat_StaticAll 1000 1640745 ns/op 549187 B/op 11186 allocs/op 109 | BenchmarkTigerTonic_StaticAll 50000 58264 ns/op 7714 B/op 157 allocs/op 110 | BenchmarkTraffic_StaticAll 500 7230129 ns/op 3763731 B/op 27453 allocs/op 111 | ``` 112 | 113 | ### Micro Benchmarks 114 | 115 | The following benchmarks measure the cost of some very basic operations. 116 | 117 | In the first benchmark, only a single route, containing a parameter, is loaded into the routers. Then a request for a URL matching this pattern is made and the router has to call the respective registered handler function. End. 118 | ``` 119 | BenchmarkBeego_Param 500000 5495 ns/op 1165 B/op 14 allocs/op 120 | BenchmarkDenco_Param 5000000 312 ns/op 50 B/op 2 allocs/op 121 | BenchmarkGocraftWeb_Param 1000000 1440 ns/op 684 B/op 9 allocs/op 122 | BenchmarkGoji_Param 5000000 748 ns/op 340 B/op 2 allocs/op 123 | BenchmarkGoJsonRest_Param 500000 6980 ns/op 1787 B/op 29 allocs/op 124 | BenchmarkGorillaMux_Param 1000000 2665 ns/op 780 B/op 7 allocs/op 125 | BenchmarkHttpRouter_Param 20000000 139 ns/op 33 B/op 1 allocs/op 126 | BenchmarkHttpTreeMux_Param 5000000 558 ns/op 340 B/op 2 allocs/op 127 | BenchmarkKocha_Param 5000000 377 ns/op 58 B/op 2 allocs/op 128 | BenchmarkMartini_Param 500000 6265 ns/op 1251 B/op 12 allocs/op 129 | BenchmarkPat_Param 1000000 1620 ns/op 670 B/op 11 allocs/op 130 | BenchmarkTigerTonic_Param 1000000 2766 ns/op 1015 B/op 18 allocs/op 131 | BenchmarkTraffic_Param 500000 4440 ns/op 2013 B/op 22 allocs/op 132 | ``` 133 | 134 | Same as before, but now with multiple parameters, all in the same single route. The intention is to see how the routers scale with the number of parameters. The values of the parameters must be passed to the handler function somehow, which requires allocations. Let's see how clever the routers solve this task with a route containing 5 and 20 parameters: 135 | ``` 136 | BenchmarkBeego_Param5 100000 18473 ns/op 1291 B/op 14 allocs/op 137 | BenchmarkDenco_Param5 2000000 982 ns/op 405 B/op 5 allocs/op 138 | BenchmarkGocraftWeb_Param5 1000000 2218 ns/op 957 B/op 12 allocs/op 139 | BenchmarkGoji_Param5 1000000 1093 ns/op 340 B/op 2 allocs/op 140 | BenchmarkGoJsonRest_Param5 200000 10462 ns/op 3264 B/op 40 allocs/op 141 | BenchmarkGorillaMux_Param5 500000 4680 ns/op 906 B/op 7 allocs/op 142 | BenchmarkHttpRouter_Param5 5000000 319 ns/op 162 B/op 1 allocs/op 143 | BenchmarkHttpTreeMux_Param5 2000000 898 ns/op 340 B/op 2 allocs/op 144 | BenchmarkKocha_Param5 1000000 1326 ns/op 448 B/op 7 allocs/op 145 | BenchmarkMartini_Param5 200000 13027 ns/op 1376 B/op 12 allocs/op 146 | BenchmarkPat_Param5 500000 3416 ns/op 1435 B/op 18 allocs/op 147 | BenchmarkTigerTonic_Param5 200000 9247 ns/op 2568 B/op 41 allocs/op 148 | BenchmarkTraffic_Param5 500000 7206 ns/op 2312 B/op 26 allocs/op 149 | 150 | BenchmarkBeego_Param20 10000 106746 ns/op 3681 B/op 17 allocs/op 151 | BenchmarkDenco_Param20 1000000 2882 ns/op 1666 B/op 7 allocs/op 152 | BenchmarkGocraftWeb_Param20 500000 7156 ns/op 3857 B/op 16 allocs/op 153 | BenchmarkGoji_Param20 1000000 3197 ns/op 1260 B/op 2 allocs/op 154 | BenchmarkGoJsonRest_Param20 100000 25809 ns/op 10605 B/op 75 allocs/op 155 | BenchmarkGorillaMux_Param20 200000 9885 ns/op 3295 B/op 9 allocs/op 156 | BenchmarkHttpRouter_Param20 2000000 954 ns/op 646 B/op 1 allocs/op 157 | BenchmarkHttpTreeMux_Param20 500000 5016 ns/op 2216 B/op 4 allocs/op 158 | BenchmarkKocha_Param20 500000 4268 ns/op 1836 B/op 17 allocs/op 159 | BenchmarkMartini_Param20 50000 55039 ns/op 3765 B/op 14 allocs/op 160 | BenchmarkPat_Param20 500000 3412 ns/op 1435 B/op 18 allocs/op 161 | BenchmarkTigerTonic_Param20 50000 36825 ns/op 10710 B/op 131 allocs/op 162 | BenchmarkTraffic_Param20 100000 22605 ns/op 8077 B/op 49 allocs/op 163 | ``` 164 | 165 | Now let's see how expensive it is to access a parameter. The handler function reads the value (by the name of the parameter, e.g. with a map lookup; depends on the router) and writes it to our [web scale storage](https://www.youtube.com/watch?v=b2F-DItXtZs) (`/dev/null`). 166 | ``` 167 | BenchmarkBeego_ParamWrite 500000 6604 ns/op 1602 B/op 18 allocs/op 168 | BenchmarkDenco_ParamWrite 5000000 377 ns/op 50 B/op 2 allocs/op 169 | BenchmarkGocraftWeb_ParamWrite 1000000 1590 ns/op 693 B/op 9 allocs/op 170 | BenchmarkGoji_ParamWrite 2000000 818 ns/op 340 B/op 2 allocs/op 171 | BenchmarkGoJsonRest_ParamWrite 200000 8388 ns/op 2265 B/op 33 allocs/op 172 | BenchmarkGorillaMux_ParamWrite 1000000 2913 ns/op 780 B/op 7 allocs/op 173 | BenchmarkHttpRouter_ParamWrite 10000000 193 ns/op 33 B/op 1 allocs/op 174 | BenchmarkHttpTreeMux_ParamWrite 5000000 649 ns/op 340 B/op 2 allocs/op 175 | BenchmarkKocha_ParamWrite 5000000 435 ns/op 58 B/op 2 allocs/op 176 | BenchmarkMartini_ParamWrite 500000 7538 ns/op 1359 B/op 15 allocs/op 177 | BenchmarkPat_ParamWrite 1000000 2940 ns/op 1109 B/op 15 allocs/op 178 | BenchmarkTigerTonic_ParamWrite 500000 4639 ns/op 1471 B/op 23 allocs/op 179 | BenchmarkTraffic_ParamWrite 500000 5855 ns/op 2435 B/op 25 allocs/op 180 | ``` 181 | 182 | ### [Parse.com](https://parse.com/docs/rest#summary) 183 | 184 | Enough of the micro benchmark stuff. Let's play a bit with real APIs. In the first set of benchmarks, we use a clone of the structure of [Parse](https://parse.com)'s decent medium-sized REST API, consisting of 26 routes. 185 | 186 | The tasks are 1.) routing a static URL (no parameters), 2.) routing a URL containing 1 parameter, 3.) same with 2 parameters, 4.) route all of the routes once (like the StaticAll benchmark, but the routes now contain parameters). 187 | 188 | Worth noting is, that the requested route might be a good case for some routing algorithms, while it is a bad case for another algorithm. The values might vary slightly depending on the selected route. 189 | 190 | ``` 191 | BenchmarkBeego_ParseStatic 500000 3461 ns/op 1247 B/op 15 allocs/op 192 | BenchmarkDenco_ParseStatic 50000000 42.6 ns/op 0 B/op 0 allocs/op 193 | BenchmarkGocraftWeb_ParseStatic 2000000 889 ns/op 328 B/op 6 allocs/op 194 | BenchmarkGoji_ParseStatic 5000000 341 ns/op 0 B/op 0 allocs/op 195 | BenchmarkGoJsonRest_ParseStatic 500000 5860 ns/op 1136 B/op 25 allocs/op 196 | BenchmarkGorillaMux_ParseStatic 1000000 2760 ns/op 456 B/op 6 allocs/op 197 | BenchmarkHttpRouter_ParseStatic 50000000 36.7 ns/op 0 B/op 0 allocs/op 198 | BenchmarkHttpTreeMux_ParseStatic 50000000 62.6 ns/op 0 B/op 0 allocs/op 199 | BenchmarkKocha_ParseStatic 50000000 72.2 ns/op 0 B/op 0 allocs/op 200 | BenchmarkMartini_ParseStatic 500000 5528 ns/op 927 B/op 11 allocs/op 201 | BenchmarkPat_ParseStatic 2000000 809 ns/op 246 B/op 5 allocs/op 202 | BenchmarkTigerTonic_ParseStatic 10000000 264 ns/op 49 B/op 1 allocs/op 203 | BenchmarkTraffic_ParseStatic 500000 5008 ns/op 2377 B/op 24 allocs/op 204 | 205 | BenchmarkBeego_ParseParam 500000 7983 ns/op 1775 B/op 28 allocs/op 206 | BenchmarkDenco_ParseParam 5000000 347 ns/op 50 B/op 2 allocs/op 207 | BenchmarkGocraftWeb_ParseParam 1000000 1535 ns/op 700 B/op 9 allocs/op 208 | BenchmarkGoji_ParseParam 2000000 983 ns/op 340 B/op 2 allocs/op 209 | BenchmarkGoJsonRest_ParseParam 500000 7208 ns/op 1789 B/op 29 allocs/op 210 | BenchmarkGorillaMux_ParseParam 1000000 3186 ns/op 780 B/op 7 allocs/op 211 | BenchmarkHttpRouter_ParseParam 10000000 178 ns/op 65 B/op 1 allocs/op 212 | BenchmarkHttpTreeMux_ParseParam 5000000 617 ns/op 340 B/op 2 allocs/op 213 | BenchmarkKocha_ParseParam 5000000 413 ns/op 58 B/op 2 allocs/op 214 | BenchmarkMartini_ParseParam 500000 7524 ns/op 1251 B/op 12 allocs/op 215 | BenchmarkPat_ParseParam 1000000 2707 ns/op 1160 B/op 18 allocs/op 216 | BenchmarkTigerTonic_ParseParam 1000000 3010 ns/op 1048 B/op 19 allocs/op 217 | BenchmarkTraffic_ParseParam 500000 5228 ns/op 2314 B/op 24 allocs/op 218 | 219 | BenchmarkBeego_Parse2Params 200000 9217 ns/op 1935 B/op 28 allocs/op 220 | BenchmarkDenco_Parse2Params 5000000 542 ns/op 115 B/op 3 allocs/op 221 | BenchmarkGocraftWeb_Parse2Params 1000000 1756 ns/op 750 B/op 10 allocs/op 222 | BenchmarkGoji_Parse2Params 2000000 954 ns/op 340 B/op 2 allocs/op 223 | BenchmarkGoJsonRest_Parse2Params 500000 8131 ns/op 2145 B/op 32 allocs/op 224 | BenchmarkGorillaMux_Parse2Params 500000 3623 ns/op 812 B/op 7 allocs/op 225 | BenchmarkHttpRouter_Parse2Params 10000000 202 ns/op 65 B/op 1 allocs/op 226 | BenchmarkHttpTreeMux_Parse2Params 5000000 708 ns/op 340 B/op 2 allocs/op 227 | BenchmarkKocha_Parse2Params 5000000 666 ns/op 132 B/op 4 allocs/op 228 | BenchmarkMartini_Parse2Params 200000 7723 ns/op 1283 B/op 12 allocs/op 229 | BenchmarkPat_Parse2Params 1000000 2687 ns/op 887 B/op 19 allocs/op 230 | BenchmarkTigerTonic_Parse2Params 500000 4720 ns/op 1473 B/op 28 allocs/op 231 | BenchmarkTraffic_Parse2Params 500000 5467 ns/op 2120 B/op 24 allocs/op 232 | 233 | BenchmarkBeego_ParseAll 10000 197920 ns/op 38877 B/op 616 allocs/op 234 | BenchmarkDenco_ParseAll 500000 7692 ns/op 1000 B/op 35 allocs/op 235 | BenchmarkGocraftWeb_ParseAll 50000 36226 ns/op 14639 B/op 208 allocs/op 236 | BenchmarkGoji_ParseAll 100000 19721 ns/op 5448 B/op 32 allocs/op 237 | BenchmarkGoJsonRest_ParseAll 10000 180128 ns/op 41202 B/op 727 allocs/op 238 | BenchmarkGorillaMux_ParseAll 10000 120929 ns/op 17138 B/op 173 allocs/op 239 | BenchmarkHttpRouter_ParseAll 500000 3592 ns/op 660 B/op 16 allocs/op 240 | BenchmarkHttpTreeMux_ParseAll 200000 11650 ns/op 5452 B/op 32 allocs/op 241 | BenchmarkKocha_ParseAll 200000 9371 ns/op 1163 B/op 44 allocs/op 242 | BenchmarkMartini_ParseAll 10000 200307 ns/op 29375 B/op 305 allocs/op 243 | BenchmarkPat_ParseAll 50000 53113 ns/op 18017 B/op 363 allocs/op 244 | BenchmarkTigerTonic_ParseAll 50000 67208 ns/op 20547 B/op 419 allocs/op 245 | BenchmarkTraffic_ParseAll 10000 164938 ns/op 70161 B/op 743 allocs/op 246 | ``` 247 | 248 | 249 | ### [GitHub](http://developer.github.com/v3/) 250 | 251 | The GitHub API is rather large, consisting of 203 routes. The tasks are basically the same as in the benchmarks before. 252 | 253 | ``` 254 | BenchmarkBeego_GithubStatic 500000 3880 ns/op 1148 B/op 31 allocs/op 255 | BenchmarkDenco_GithubStatic 50000000 60.5 ns/op 0 B/op 0 allocs/op 256 | BenchmarkGocraftWeb_GithubStatic 2000000 933 ns/op 328 B/op 6 allocs/op 257 | BenchmarkGoji_GithubStatic 5000000 401 ns/op 0 B/op 0 allocs/op 258 | BenchmarkGoJsonRest_GithubStatic 500000 6006 ns/op 1150 B/op 25 allocs/op 259 | BenchmarkGorillaMux_GithubStatic 100000 18227 ns/op 456 B/op 6 allocs/op 260 | BenchmarkHttpRouter_GithubStatic 50000000 63.2 ns/op 0 B/op 0 allocs/op 261 | BenchmarkHttpTreeMux_GithubStatic 50000000 65.1 ns/op 0 B/op 0 allocs/op 262 | BenchmarkKocha_GithubStatic 20000000 99.5 ns/op 0 B/op 0 allocs/op 263 | BenchmarkMartini_GithubStatic 100000 18546 ns/op 927 B/op 11 allocs/op 264 | BenchmarkPat_GithubStatic 200000 11503 ns/op 3754 B/op 76 allocs/op 265 | BenchmarkTigerTonic_GithubStatic 5000000 308 ns/op 49 B/op 1 allocs/op 266 | BenchmarkTraffic_GithubStatic 50000 44923 ns/op 23105 B/op 168 allocs/op 267 | 268 | BenchmarkBeego_GithubParam 50000 44645 ns/op 2973 B/op 50 allocs/op 269 | BenchmarkDenco_GithubParam 5000000 643 ns/op 115 B/op 3 allocs/op 270 | BenchmarkGocraftWeb_GithubParam 1000000 1855 ns/op 750 B/op 10 allocs/op 271 | BenchmarkGoji_GithubParam 1000000 1314 ns/op 340 B/op 2 allocs/op 272 | BenchmarkGoJsonRest_GithubParam 200000 8427 ns/op 2159 B/op 32 allocs/op 273 | BenchmarkGorillaMux_GithubParam 200000 11485 ns/op 813 B/op 7 allocs/op 274 | BenchmarkHttpRouter_GithubParam 5000000 304 ns/op 97 B/op 1 allocs/op 275 | BenchmarkHttpTreeMux_GithubParam 2000000 770 ns/op 340 B/op 2 allocs/op 276 | BenchmarkKocha_GithubParam 5000000 754 ns/op 132 B/op 4 allocs/op 277 | BenchmarkMartini_GithubParam 100000 22637 ns/op 1284 B/op 12 allocs/op 278 | BenchmarkPat_GithubParam 500000 7319 ns/op 2538 B/op 44 allocs/op 279 | BenchmarkTigerTonic_GithubParam 500000 4722 ns/op 1467 B/op 26 allocs/op 280 | BenchmarkTraffic_GithubParam 100000 18700 ns/op 7076 B/op 58 allocs/op 281 | 282 | BenchmarkBeego_GithubAll 100 23430165 ns/op 502614 B/op 9871 allocs/op 283 | BenchmarkDenco_GithubAll 10000 120365 ns/op 21219 B/op 506 allocs/op 284 | BenchmarkGocraftWeb_GithubAll 5000 358982 ns/op 139091 B/op 1903 allocs/op 285 | BenchmarkGoji_GithubAll 5000 604522 ns/op 56896 B/op 340 allocs/op 286 | BenchmarkGoJsonRest_GithubAll 1000 1645794 ns/op 404222 B/op 6303 allocs/op 287 | BenchmarkGorillaMux_GithubAll 500 6634737 ns/op 152277 B/op 1402 allocs/op 288 | BenchmarkHttpRouter_GithubAll 50000 51138 ns/op 14039 B/op 168 allocs/op 289 | BenchmarkHttpTreeMux_GithubAll 10000 132507 ns/op 56907 B/op 340 allocs/op 290 | BenchmarkKocha_GithubAll 10000 143398 ns/op 24117 B/op 676 allocs/op 291 | BenchmarkMartini_GithubAll 200 9802351 ns/op 258349 B/op 2713 allocs/op 292 | BenchmarkPat_GithubAll 500 4154815 ns/op 1539081 B/op 24970 allocs/op 293 | BenchmarkTigerTonic_GithubAll 2000 920839 ns/op 247085 B/op 5171 allocs/op 294 | BenchmarkTraffic_GithubAll 200 8087393 ns/op 3143039 B/op 23958 allocs/op 295 | ``` 296 | 297 | ### [Google+](https://developers.google.com/+/api/latest/) 298 | 299 | Last but not least the Google+ API, consisting of 13 routes. In reality this is just a subset of a much larger API. 300 | 301 | ``` 302 | BenchmarkBeego_GPlusStatic 1000000 2321 ns/op 808 B/op 11 allocs/op 303 | BenchmarkDenco_GPlusStatic 50000000 37.2 ns/op 0 B/op 0 allocs/op 304 | BenchmarkGocraftWeb_GPlusStatic 2000000 862 ns/op 312 B/op 6 allocs/op 305 | BenchmarkGoji_GPlusStatic 10000000 270 ns/op 0 B/op 0 allocs/op 306 | BenchmarkGoJsonRest_GPlusStatic 500000 5827 ns/op 1136 B/op 25 allocs/op 307 | BenchmarkGorillaMux_GPlusStatic 1000000 1793 ns/op 456 B/op 6 allocs/op 308 | BenchmarkHttpRouter_GPlusStatic 50000000 34.6 ns/op 0 B/op 0 allocs/op 309 | BenchmarkHttpTreeMux_GPlusStatic 50000000 35.4 ns/op 0 B/op 0 allocs/op 310 | BenchmarkKocha_GPlusStatic 50000000 63.8 ns/op 0 B/op 0 allocs/op 311 | BenchmarkMartini_GPlusStatic 500000 4887 ns/op 927 B/op 11 allocs/op 312 | BenchmarkPat_GPlusStatic 5000000 336 ns/op 98 B/op 2 allocs/op 313 | BenchmarkTigerTonic_GPlusStatic 10000000 186 ns/op 33 B/op 1 allocs/op 314 | BenchmarkTraffic_GPlusStatic 500000 3350 ns/op 1503 B/op 18 allocs/op 315 | 316 | BenchmarkBeego_GPlusParam 200000 7657 ns/op 1231 B/op 16 allocs/op 317 | BenchmarkDenco_GPlusParam 5000000 365 ns/op 50 B/op 2 allocs/op 318 | BenchmarkGocraftWeb_GPlusParam 1000000 1519 ns/op 684 B/op 9 allocs/op 319 | BenchmarkGoji_GPlusParam 2000000 889 ns/op 340 B/op 2 allocs/op 320 | BenchmarkGoJsonRest_GPlusParam 500000 7388 ns/op 1806 B/op 29 allocs/op 321 | BenchmarkGorillaMux_GPlusParam 500000 4040 ns/op 780 B/op 7 allocs/op 322 | BenchmarkHttpRouter_GPlusParam 10000000 203 ns/op 65 B/op 1 allocs/op 323 | BenchmarkHttpTreeMux_GPlusParam 5000000 638 ns/op 340 B/op 2 allocs/op 324 | BenchmarkKocha_GPlusParam 5000000 444 ns/op 58 B/op 2 allocs/op 325 | BenchmarkMartini_GPlusParam 200000 8672 ns/op 1251 B/op 12 allocs/op 326 | BenchmarkPat_GPlusParam 1000000 1895 ns/op 719 B/op 12 allocs/op 327 | BenchmarkTigerTonic_GPlusParam 1000000 3166 ns/op 1085 B/op 18 allocs/op 328 | BenchmarkTraffic_GPlusParam 500000 5369 ns/op 2030 B/op 22 allocs/op 329 | 330 | BenchmarkBeego_GPlus2Params 200000 9999 ns/op 1293 B/op 16 allocs/op 331 | BenchmarkDenco_GPlus2Params 5000000 618 ns/op 115 B/op 3 allocs/op 332 | BenchmarkGocraftWeb_GPlus2Params 1000000 1860 ns/op 750 B/op 10 allocs/op 333 | BenchmarkGoji_GPlus2Params 1000000 1296 ns/op 340 B/op 2 allocs/op 334 | BenchmarkGoJsonRest_GPlus2Params 200000 8516 ns/op 2178 B/op 32 allocs/op 335 | BenchmarkGorillaMux_GPlus2Params 200000 9007 ns/op 812 B/op 7 allocs/op 336 | BenchmarkHttpRouter_GPlus2Params 10000000 246 ns/op 65 B/op 1 allocs/op 337 | BenchmarkHttpTreeMux_GPlus2Params 2000000 751 ns/op 340 B/op 2 allocs/op 338 | BenchmarkKocha_GPlus2Params 5000000 744 ns/op 132 B/op 4 allocs/op 339 | BenchmarkMartini_GPlus2Params 100000 27700 ns/op 1382 B/op 16 allocs/op 340 | BenchmarkPat_GPlus2Params 500000 5981 ns/op 2347 B/op 34 allocs/op 341 | BenchmarkTigerTonic_GPlus2Params 500000 5076 ns/op 1561 B/op 27 allocs/op 342 | BenchmarkTraffic_GPlus2Params 200000 12711 ns/op 3599 B/op 34 allocs/op 343 | 344 | BenchmarkBeego_GPlusAll 10000 113601 ns/op 15897 B/op 217 allocs/op 345 | BenchmarkDenco_GPlusAll 500000 5761 ns/op 880 B/op 27 allocs/op 346 | BenchmarkGocraftWeb_GPlusAll 100000 20527 ns/op 8513 B/op 116 allocs/op 347 | BenchmarkGoji_GPlusAll 200000 12312 ns/op 3746 B/op 22 allocs/op 348 | BenchmarkGoJsonRest_GPlusAll 20000 99250 ns/op 23871 B/op 386 allocs/op 349 | BenchmarkGorillaMux_GPlusAll 50000 63046 ns/op 9655 B/op 90 allocs/op 350 | BenchmarkHttpRouter_GPlusAll 1000000 2513 ns/op 655 B/op 11 allocs/op 351 | BenchmarkHttpTreeMux_GPlusAll 500000 7706 ns/op 3748 B/op 22 allocs/op 352 | BenchmarkKocha_GPlusAll 500000 6858 ns/op 1017 B/op 35 allocs/op 353 | BenchmarkMartini_GPlusAll 10000 155402 ns/op 16368 B/op 179 allocs/op 354 | BenchmarkPat_GPlusAll 50000 47397 ns/op 17270 B/op 302 allocs/op 355 | BenchmarkTigerTonic_GPlusAll 50000 49864 ns/op 15160 B/op 311 allocs/op 356 | BenchmarkTraffic_GPlusAll 10000 108007 ns/op 41779 B/op 430 allocs/op 357 | ``` 358 | 359 | 360 | ## Conclusions 361 | First of all, there is no reason to use net/http's default [ServeMux](http://golang.org/pkg/net/http/#ServeMux), which is very limited and does not have especially good performance. There are enough alternatives coming in every flavor, choose the one you like best. 362 | 363 | Secondly, the broad range of functions of some of the frameworks comes at a high price in terms of performance. For example Martini has great flexibility, but very bad performance. Martini has the worst performance of all tested routers in a lot of the benchmarks. Beego seems to have some scalability problems and easily defeats Martini with even worse performance, when the number of parameters or routes is high. I really hope, that the routing of these packages can be optimized. I think the Go-ecosystem needs great feature-rich frameworks like these. 364 | 365 | Last but not least, we have to determine the performance champion. 366 | 367 | Denco and its predecessor Kocha-urlrouter seem to have great performance, but are not convenient to use as a router for the net/http package. A lot of extra work is necessary to use it as a http.Handler. [The README of Denco claims](https://github.com/naoina/denco/blob/b03dbb499269a597afd0db715d408ebba1329d04/README.md), that the package is not intended as a replacement for [http.ServeMux](http://golang.org/pkg/net/http/#ServeMux). 368 | 369 | [Goji](https://github.com/zenazn/goji/) looks very decent. It has great performance while also having a great range of features, more than any other router / framework in the top group. 370 | 371 | Currently no router can beat the performance of the [HttpRouter](https://github.com/julienschmidt/httprouter) package, which currently dominates nearly all benchmarks. 372 | 373 | In the end, performance can not be the (only) criterion for choosing a router. Play around a bit with some of the routers, and choose the one you like best. 374 | 375 | ## Usage 376 | 377 | If you'd like to run these benchmarks locally, you'll need to install the package first: 378 | 379 | ```bash 380 | go get github.com/julienschmidt/go-http-routing-benchmark 381 | ``` 382 | This may take a while due to the large number of dependencies that need to be downloaded. Once that command has finished you can run the full set of benchmarks like this: 383 | 384 | ```bash 385 | cd $GOPATH/src/github.com/julienschmidt/go-http-routing-benchmark 386 | go test -bench=. 387 | ``` 388 | 389 | > **Note:** If you run the tests and it SIGQUIT's make the go test timeout longer (#44) 390 | > 391 | ``` 392 | go test -timeout=2h -bench=. 393 | ``` 394 | 395 | 396 | You can bench specific frameworks only by using a regular expression as the value of the `bench` parameter: 397 | ```bash 398 | go test -bench="Martini|Gin|HttpMux" 399 | ``` 400 | -------------------------------------------------------------------------------- /bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Julien Schmidt. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be found 3 | // in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "net/http" 9 | "os" 10 | "regexp" 11 | "runtime" 12 | "strings" 13 | "testing" 14 | ) 15 | 16 | var benchRe *regexp.Regexp 17 | 18 | func isTested(name string) bool { 19 | if benchRe == nil { 20 | // Get -test.bench flag value (not accessible via flag package) 21 | bench := "" 22 | for _, arg := range os.Args { 23 | if strings.HasPrefix(arg, "-test.bench=") { 24 | // ignore the benchmark name after an underscore 25 | bench = strings.SplitN(arg[12:], "_", 2)[0] 26 | break 27 | } 28 | } 29 | 30 | // Compile RegExp to match Benchmark names 31 | var err error 32 | benchRe, err = regexp.Compile(bench) 33 | if err != nil { 34 | panic(err.Error()) 35 | } 36 | } 37 | return benchRe.MatchString(name) 38 | } 39 | 40 | func calcMem(name string, load func()) { 41 | if !isTested(name) { 42 | return 43 | } 44 | 45 | m := new(runtime.MemStats) 46 | 47 | // before 48 | // force GC multiple times, since Go is using a generational GC 49 | // TODO: find a better approach 50 | runtime.GC() 51 | runtime.GC() 52 | runtime.GC() 53 | runtime.GC() 54 | runtime.ReadMemStats(m) 55 | before := m.HeapAlloc 56 | 57 | load() 58 | 59 | // after 60 | runtime.GC() 61 | runtime.GC() 62 | runtime.GC() 63 | runtime.GC() 64 | runtime.ReadMemStats(m) 65 | after := m.HeapAlloc 66 | println(" "+name+":", after-before, "Bytes") 67 | } 68 | 69 | func benchRequest(b *testing.B, router http.Handler, r *http.Request) { 70 | w := new(mockResponseWriter) 71 | u := r.URL 72 | rq := u.RawQuery 73 | r.RequestURI = u.RequestURI() 74 | 75 | b.ReportAllocs() 76 | b.ResetTimer() 77 | 78 | for i := 0; i < b.N; i++ { 79 | u.RawQuery = rq 80 | router.ServeHTTP(w, r) 81 | } 82 | } 83 | 84 | func benchRoutes(b *testing.B, router http.Handler, routes []route) { 85 | w := new(mockResponseWriter) 86 | r, _ := http.NewRequest("GET", "/", nil) 87 | u := r.URL 88 | rq := u.RawQuery 89 | 90 | b.ReportAllocs() 91 | b.ResetTimer() 92 | 93 | for i := 0; i < b.N; i++ { 94 | for _, route := range routes { 95 | r.Method = route.method 96 | r.RequestURI = route.path 97 | u.Path = route.path 98 | u.RawQuery = rq 99 | router.ServeHTTP(w, r) 100 | } 101 | } 102 | } 103 | 104 | // Micro Benchmarks 105 | 106 | // Route with Param (no write) 107 | func BenchmarkAce_Param(b *testing.B) { 108 | router := loadAceSingle("GET", "/user/:name", aceHandle) 109 | 110 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 111 | benchRequest(b, router, r) 112 | } 113 | func BenchmarkAero_Param(b *testing.B) { 114 | router := loadAeroSingle("GET", "/user/:name", aeroHandler) 115 | 116 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 117 | benchRequest(b, router, r) 118 | } 119 | func BenchmarkBear_Param(b *testing.B) { 120 | router := loadBearSingle("GET", "/user/{name}", bearHandler) 121 | 122 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 123 | benchRequest(b, router, r) 124 | } 125 | func BenchmarkBeego_Param(b *testing.B) { 126 | router := loadBeegoSingle("GET", "/user/:name", beegoHandler) 127 | 128 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 129 | benchRequest(b, router, r) 130 | } 131 | func BenchmarkBone_Param(b *testing.B) { 132 | router := loadBoneSingle("GET", "/user/:name", http.HandlerFunc(httpHandlerFunc)) 133 | 134 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 135 | benchRequest(b, router, r) 136 | } 137 | func BenchmarkChi_Param(b *testing.B) { 138 | router := loadChiSingle("GET", "/user/{name}", httpHandlerFunc) 139 | 140 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 141 | benchRequest(b, router, r) 142 | } 143 | func BenchmarkCloudyKitRouter_Param(b *testing.B) { 144 | router := loadCloudyKitRouterSingle("GET", "/user/:name", cloudyKitRouterHandler) 145 | 146 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 147 | benchRequest(b, router, r) 148 | } 149 | func BenchmarkDenco_Param(b *testing.B) { 150 | router := loadDencoSingle("GET", "/user/:name", dencoHandler) 151 | 152 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 153 | benchRequest(b, router, r) 154 | } 155 | func BenchmarkEcho_Param(b *testing.B) { 156 | router := loadEchoSingle("GET", "/user/:name", echoHandler) 157 | 158 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 159 | benchRequest(b, router, r) 160 | } 161 | func BenchmarkGin_Param(b *testing.B) { 162 | router := loadGinSingle("GET", "/user/:name", ginHandle) 163 | 164 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 165 | benchRequest(b, router, r) 166 | } 167 | func BenchmarkGocraftWeb_Param(b *testing.B) { 168 | router := loadGocraftWebSingle("GET", "/user/:name", gocraftWebHandler) 169 | 170 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 171 | benchRequest(b, router, r) 172 | } 173 | func BenchmarkGoji_Param(b *testing.B) { 174 | router := loadGojiSingle("GET", "/user/:name", httpHandlerFunc) 175 | 176 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 177 | benchRequest(b, router, r) 178 | } 179 | func BenchmarkGojiv2_Param(b *testing.B) { 180 | router := loadGojiv2Single("GET", "/user/:name", gojiv2Handler) 181 | 182 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 183 | benchRequest(b, router, r) 184 | } 185 | func BenchmarkGoJsonRest_Param(b *testing.B) { 186 | router := loadGoJsonRestSingle("GET", "/user/:name", goJsonRestHandler) 187 | 188 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 189 | benchRequest(b, router, r) 190 | } 191 | func BenchmarkGoRestful_Param(b *testing.B) { 192 | router := loadGoRestfulSingle("GET", "/user/{name}", goRestfulHandler) 193 | 194 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 195 | benchRequest(b, router, r) 196 | } 197 | func BenchmarkGorillaMux_Param(b *testing.B) { 198 | router := loadGorillaMuxSingle("GET", "/user/{name}", httpHandlerFunc) 199 | 200 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 201 | benchRequest(b, router, r) 202 | } 203 | func BenchmarkGowwwRouter_Param(b *testing.B) { 204 | router := loadGowwwRouterSingle("GET", "/user/:name", http.HandlerFunc(httpHandlerFunc)) 205 | 206 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 207 | benchRequest(b, router, r) 208 | } 209 | func BenchmarkHttpRouter_Param(b *testing.B) { 210 | router := loadHttpRouterSingle("GET", "/user/:name", httpRouterHandle) 211 | 212 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 213 | benchRequest(b, router, r) 214 | } 215 | func BenchmarkHttpTreeMux_Param(b *testing.B) { 216 | router := loadHttpTreeMuxSingle("GET", "/user/:name", httpTreeMuxHandler) 217 | 218 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 219 | benchRequest(b, router, r) 220 | } 221 | func BenchmarkKocha_Param(b *testing.B) { 222 | handler := new(kochaHandler) 223 | router := loadKochaSingle( 224 | "GET", "/user/:name", 225 | handler, http.HandlerFunc(handler.Get), 226 | ) 227 | 228 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 229 | benchRequest(b, router, r) 230 | } 231 | func BenchmarkLARS_Param(b *testing.B) { 232 | router := loadLARSSingle("GET", "/user/:name", larsHandler) 233 | 234 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 235 | benchRequest(b, router, r) 236 | } 237 | func BenchmarkMacaron_Param(b *testing.B) { 238 | router := loadMacaronSingle("GET", "/user/:name", macaronHandler) 239 | 240 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 241 | benchRequest(b, router, r) 242 | } 243 | func BenchmarkMartini_Param(b *testing.B) { 244 | router := loadMartiniSingle("GET", "/user/:name", martiniHandler) 245 | 246 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 247 | benchRequest(b, router, r) 248 | } 249 | func BenchmarkPat_Param(b *testing.B) { 250 | router := loadPatSingle("GET", "/user/:name", http.HandlerFunc(httpHandlerFunc)) 251 | 252 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 253 | benchRequest(b, router, r) 254 | } 255 | func BenchmarkPossum_Param(b *testing.B) { 256 | router := loadPossumSingle("GET", "/user/:name", possumHandler) 257 | 258 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 259 | benchRequest(b, router, r) 260 | } 261 | func BenchmarkR2router_Param(b *testing.B) { 262 | router := loadR2routerSingle("GET", "/user/:name", r2routerHandler) 263 | 264 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 265 | benchRequest(b, router, r) 266 | } 267 | 268 | // func BenchmarkRevel_Param(b *testing.B) { 269 | // router := loadRevelSingle("GET", "/user/:name", "RevelController.Handle") 270 | 271 | // r, _ := http.NewRequest("GET", "/user/gordon", nil) 272 | // benchRequest(b, router, r) 273 | // } 274 | func BenchmarkRivet_Param(b *testing.B) { 275 | router := loadRivetSingle("GET", "/user/:name", rivetHandler) 276 | 277 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 278 | benchRequest(b, router, r) 279 | } 280 | func BenchmarkTango_Param(b *testing.B) { 281 | router := loadTangoSingle("GET", "/user/:name", tangoHandler) 282 | 283 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 284 | benchRequest(b, router, r) 285 | } 286 | func BenchmarkTigerTonic_Param(b *testing.B) { 287 | router := loadTigerTonicSingle("GET", "/user/{name}", httpHandlerFunc) 288 | 289 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 290 | benchRequest(b, router, r) 291 | } 292 | func BenchmarkTraffic_Param(b *testing.B) { 293 | router := loadTrafficSingle("GET", "/user/:name", trafficHandler) 294 | 295 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 296 | benchRequest(b, router, r) 297 | } 298 | func BenchmarkVulcan_Param(b *testing.B) { 299 | router := loadVulcanSingle("GET", "/user/:name", vulcanHandler) 300 | 301 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 302 | benchRequest(b, router, r) 303 | } 304 | 305 | // func BenchmarkZeus_Param(b *testing.B) { 306 | // router := loadZeusSingle("GET", "/user/:name", http.HandlerFunc(httpHandlerFunc)) 307 | 308 | // r, _ := http.NewRequest("GET", "/user/gordon", nil) 309 | // benchRequest(b, router, r) 310 | // } 311 | 312 | // Route with 5 Params (no write) 313 | const fiveColon = "/:a/:b/:c/:d/:e" 314 | const fiveBrace = "/{a}/{b}/{c}/{d}/{e}" 315 | const fiveRoute = "/test/test/test/test/test" 316 | 317 | func BenchmarkAce_Param5(b *testing.B) { 318 | router := loadAceSingle("GET", fiveColon, aceHandle) 319 | 320 | r, _ := http.NewRequest("GET", fiveRoute, nil) 321 | benchRequest(b, router, r) 322 | } 323 | func BenchmarkAero_Param5(b *testing.B) { 324 | router := loadAeroSingle("GET", fiveColon, aeroHandler) 325 | 326 | r, _ := http.NewRequest("GET", fiveRoute, nil) 327 | benchRequest(b, router, r) 328 | } 329 | func BenchmarkBear_Param5(b *testing.B) { 330 | router := loadBearSingle("GET", fiveBrace, bearHandler) 331 | 332 | r, _ := http.NewRequest("GET", fiveRoute, nil) 333 | benchRequest(b, router, r) 334 | } 335 | func BenchmarkBeego_Param5(b *testing.B) { 336 | router := loadBeegoSingle("GET", fiveColon, beegoHandler) 337 | 338 | r, _ := http.NewRequest("GET", fiveRoute, nil) 339 | benchRequest(b, router, r) 340 | } 341 | func BenchmarkBone_Param5(b *testing.B) { 342 | router := loadBoneSingle("GET", fiveColon, http.HandlerFunc(httpHandlerFunc)) 343 | 344 | r, _ := http.NewRequest("GET", fiveRoute, nil) 345 | benchRequest(b, router, r) 346 | } 347 | func BenchmarkChi_Param5(b *testing.B) { 348 | router := loadChiSingle("GET", fiveBrace, httpHandlerFunc) 349 | 350 | r, _ := http.NewRequest("GET", fiveRoute, nil) 351 | benchRequest(b, router, r) 352 | } 353 | func BenchmarkCloudyKitRouter_Param5(b *testing.B) { 354 | router := loadCloudyKitRouterSingle("GET", fiveColon, cloudyKitRouterHandler) 355 | 356 | r, _ := http.NewRequest("GET", fiveRoute, nil) 357 | benchRequest(b, router, r) 358 | } 359 | func BenchmarkDenco_Param5(b *testing.B) { 360 | router := loadDencoSingle("GET", fiveColon, dencoHandler) 361 | 362 | r, _ := http.NewRequest("GET", fiveRoute, nil) 363 | benchRequest(b, router, r) 364 | } 365 | func BenchmarkEcho_Param5(b *testing.B) { 366 | router := loadEchoSingle("GET", fiveColon, echoHandler) 367 | 368 | r, _ := http.NewRequest("GET", fiveRoute, nil) 369 | benchRequest(b, router, r) 370 | } 371 | func BenchmarkGin_Param5(b *testing.B) { 372 | router := loadGinSingle("GET", fiveColon, ginHandle) 373 | 374 | r, _ := http.NewRequest("GET", fiveRoute, nil) 375 | benchRequest(b, router, r) 376 | } 377 | func BenchmarkGocraftWeb_Param5(b *testing.B) { 378 | router := loadGocraftWebSingle("GET", fiveColon, gocraftWebHandler) 379 | 380 | r, _ := http.NewRequest("GET", fiveRoute, nil) 381 | benchRequest(b, router, r) 382 | } 383 | func BenchmarkGoji_Param5(b *testing.B) { 384 | router := loadGojiSingle("GET", fiveColon, httpHandlerFunc) 385 | 386 | r, _ := http.NewRequest("GET", fiveRoute, nil) 387 | benchRequest(b, router, r) 388 | } 389 | func BenchmarkGojiv2_Param5(b *testing.B) { 390 | router := loadGojiv2Single("GET", fiveColon, gojiv2Handler) 391 | 392 | r, _ := http.NewRequest("GET", fiveRoute, nil) 393 | benchRequest(b, router, r) 394 | } 395 | func BenchmarkGoJsonRest_Param5(b *testing.B) { 396 | handler := loadGoJsonRestSingle("GET", fiveColon, goJsonRestHandler) 397 | 398 | r, _ := http.NewRequest("GET", fiveRoute, nil) 399 | benchRequest(b, handler, r) 400 | } 401 | func BenchmarkGoRestful_Param5(b *testing.B) { 402 | router := loadGoRestfulSingle("GET", fiveBrace, goRestfulHandler) 403 | 404 | r, _ := http.NewRequest("GET", fiveRoute, nil) 405 | benchRequest(b, router, r) 406 | } 407 | func BenchmarkGorillaMux_Param5(b *testing.B) { 408 | router := loadGorillaMuxSingle("GET", fiveBrace, httpHandlerFunc) 409 | 410 | r, _ := http.NewRequest("GET", fiveRoute, nil) 411 | benchRequest(b, router, r) 412 | } 413 | func BenchmarkGowwwRouter_Param5(b *testing.B) { 414 | router := loadGowwwRouterSingle("GET", fiveColon, http.HandlerFunc(httpHandlerFunc)) 415 | 416 | r, _ := http.NewRequest("GET", fiveRoute, nil) 417 | benchRequest(b, router, r) 418 | } 419 | func BenchmarkHttpRouter_Param5(b *testing.B) { 420 | router := loadHttpRouterSingle("GET", fiveColon, httpRouterHandle) 421 | 422 | r, _ := http.NewRequest("GET", fiveRoute, nil) 423 | benchRequest(b, router, r) 424 | } 425 | func BenchmarkHttpTreeMux_Param5(b *testing.B) { 426 | router := loadHttpTreeMuxSingle("GET", fiveColon, httpTreeMuxHandler) 427 | 428 | r, _ := http.NewRequest("GET", fiveRoute, nil) 429 | benchRequest(b, router, r) 430 | } 431 | func BenchmarkKocha_Param5(b *testing.B) { 432 | handler := new(kochaHandler) 433 | router := loadKochaSingle( 434 | "GET", fiveColon, 435 | handler, http.HandlerFunc(handler.Get), 436 | ) 437 | 438 | r, _ := http.NewRequest("GET", fiveRoute, nil) 439 | benchRequest(b, router, r) 440 | } 441 | func BenchmarkLARS_Param5(b *testing.B) { 442 | router := loadLARSSingle("GET", fiveColon, larsHandler) 443 | 444 | r, _ := http.NewRequest("GET", fiveRoute, nil) 445 | benchRequest(b, router, r) 446 | } 447 | func BenchmarkMacaron_Param5(b *testing.B) { 448 | router := loadMacaronSingle("GET", fiveColon, macaronHandler) 449 | 450 | r, _ := http.NewRequest("GET", fiveRoute, nil) 451 | benchRequest(b, router, r) 452 | } 453 | func BenchmarkMartini_Param5(b *testing.B) { 454 | router := loadMartiniSingle("GET", fiveColon, martiniHandler) 455 | 456 | r, _ := http.NewRequest("GET", fiveRoute, nil) 457 | benchRequest(b, router, r) 458 | } 459 | func BenchmarkPat_Param5(b *testing.B) { 460 | router := loadPatSingle("GET", fiveColon, http.HandlerFunc(httpHandlerFunc)) 461 | 462 | r, _ := http.NewRequest("GET", fiveRoute, nil) 463 | benchRequest(b, router, r) 464 | } 465 | func BenchmarkPossum_Param5(b *testing.B) { 466 | router := loadPossumSingle("GET", fiveColon, possumHandler) 467 | 468 | r, _ := http.NewRequest("GET", fiveRoute, nil) 469 | benchRequest(b, router, r) 470 | } 471 | func BenchmarkR2router_Param5(b *testing.B) { 472 | router := loadR2routerSingle("GET", fiveColon, r2routerHandler) 473 | 474 | r, _ := http.NewRequest("GET", fiveRoute, nil) 475 | benchRequest(b, router, r) 476 | } 477 | 478 | // func BenchmarkRevel_Param5(b *testing.B) { 479 | // router := loadRevelSingle("GET", fiveColon, "RevelController.Handle") 480 | 481 | // r, _ := http.NewRequest("GET", fiveRoute, nil) 482 | // benchRequest(b, router, r) 483 | // } 484 | func BenchmarkRivet_Param5(b *testing.B) { 485 | router := loadRivetSingle("GET", fiveColon, rivetHandler) 486 | 487 | r, _ := http.NewRequest("GET", fiveRoute, nil) 488 | benchRequest(b, router, r) 489 | } 490 | func BenchmarkTango_Param5(b *testing.B) { 491 | router := loadTangoSingle("GET", fiveColon, tangoHandler) 492 | 493 | r, _ := http.NewRequest("GET", fiveRoute, nil) 494 | benchRequest(b, router, r) 495 | } 496 | func BenchmarkTigerTonic_Param5(b *testing.B) { 497 | router := loadTigerTonicSingle("GET", fiveBrace, httpHandlerFunc) 498 | 499 | r, _ := http.NewRequest("GET", fiveRoute, nil) 500 | benchRequest(b, router, r) 501 | } 502 | func BenchmarkTraffic_Param5(b *testing.B) { 503 | router := loadTrafficSingle("GET", fiveColon, trafficHandler) 504 | 505 | r, _ := http.NewRequest("GET", fiveRoute, nil) 506 | benchRequest(b, router, r) 507 | } 508 | func BenchmarkVulcan_Param5(b *testing.B) { 509 | router := loadVulcanSingle("GET", fiveColon, vulcanHandler) 510 | 511 | r, _ := http.NewRequest("GET", fiveRoute, nil) 512 | benchRequest(b, router, r) 513 | } 514 | 515 | // func BenchmarkZeus_Param5(b *testing.B) { 516 | // router := loadZeusSingle("GET", fiveColon, http.HandlerFunc(httpHandlerFunc)) 517 | 518 | // r, _ := http.NewRequest("GET", fiveRoute, nil) 519 | // benchRequest(b, router, r) 520 | // } 521 | 522 | // Route with 20 Params (no write) 523 | const twentyColon = "/:a/:b/:c/:d/:e/:f/:g/:h/:i/:j/:k/:l/:m/:n/:o/:p/:q/:r/:s/:t" 524 | const twentyBrace = "/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}/{j}/{k}/{l}/{m}/{n}/{o}/{p}/{q}/{r}/{s}/{t}" 525 | const twentyRoute = "/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t" 526 | 527 | func BenchmarkAce_Param20(b *testing.B) { 528 | router := loadAceSingle("GET", twentyColon, aceHandle) 529 | 530 | r, _ := http.NewRequest("GET", twentyRoute, nil) 531 | benchRequest(b, router, r) 532 | } 533 | func BenchmarkAero_Param20(b *testing.B) { 534 | router := loadAeroSingle("GET", twentyBrace, aeroHandler) 535 | 536 | r, _ := http.NewRequest("GET", twentyRoute, nil) 537 | benchRequest(b, router, r) 538 | } 539 | func BenchmarkBear_Param20(b *testing.B) { 540 | router := loadBearSingle("GET", twentyBrace, bearHandler) 541 | 542 | r, _ := http.NewRequest("GET", twentyRoute, nil) 543 | benchRequest(b, router, r) 544 | } 545 | func BenchmarkBeego_Param20(b *testing.B) { 546 | router := loadBeegoSingle("GET", twentyColon, beegoHandler) 547 | 548 | r, _ := http.NewRequest("GET", twentyRoute, nil) 549 | benchRequest(b, router, r) 550 | } 551 | func BenchmarkBone_Param20(b *testing.B) { 552 | router := loadBoneSingle("GET", twentyColon, http.HandlerFunc(httpHandlerFunc)) 553 | 554 | r, _ := http.NewRequest("GET", twentyRoute, nil) 555 | benchRequest(b, router, r) 556 | } 557 | func BenchmarkChi_Param20(b *testing.B) { 558 | router := loadChiSingle("GET", twentyBrace, httpHandlerFunc) 559 | 560 | r, _ := http.NewRequest("GET", twentyRoute, nil) 561 | benchRequest(b, router, r) 562 | } 563 | func BenchmarkCloudyKitRouter_Param20(b *testing.B) { 564 | router := loadCloudyKitRouterSingle("GET", twentyColon, cloudyKitRouterHandler) 565 | 566 | r, _ := http.NewRequest("GET", twentyRoute, nil) 567 | benchRequest(b, router, r) 568 | } 569 | func BenchmarkDenco_Param20(b *testing.B) { 570 | router := loadDencoSingle("GET", twentyColon, dencoHandler) 571 | 572 | r, _ := http.NewRequest("GET", twentyRoute, nil) 573 | benchRequest(b, router, r) 574 | } 575 | func BenchmarkEcho_Param20(b *testing.B) { 576 | router := loadEchoSingle("GET", twentyColon, echoHandler) 577 | 578 | r, _ := http.NewRequest("GET", twentyRoute, nil) 579 | benchRequest(b, router, r) 580 | } 581 | func BenchmarkGin_Param20(b *testing.B) { 582 | router := loadGinSingle("GET", twentyColon, ginHandle) 583 | 584 | r, _ := http.NewRequest("GET", twentyRoute, nil) 585 | benchRequest(b, router, r) 586 | } 587 | func BenchmarkGocraftWeb_Param20(b *testing.B) { 588 | router := loadGocraftWebSingle("GET", twentyColon, gocraftWebHandler) 589 | 590 | r, _ := http.NewRequest("GET", twentyRoute, nil) 591 | benchRequest(b, router, r) 592 | } 593 | func BenchmarkGoji_Param20(b *testing.B) { 594 | router := loadGojiSingle("GET", twentyColon, httpHandlerFunc) 595 | 596 | r, _ := http.NewRequest("GET", twentyRoute, nil) 597 | benchRequest(b, router, r) 598 | } 599 | func BenchmarkGojiv2_Param20(b *testing.B) { 600 | router := loadGojiv2Single("GET", twentyColon, gojiv2Handler) 601 | 602 | r, _ := http.NewRequest("GET", twentyRoute, nil) 603 | benchRequest(b, router, r) 604 | } 605 | func BenchmarkGoJsonRest_Param20(b *testing.B) { 606 | handler := loadGoJsonRestSingle("GET", twentyColon, goJsonRestHandler) 607 | 608 | r, _ := http.NewRequest("GET", twentyRoute, nil) 609 | benchRequest(b, handler, r) 610 | } 611 | func BenchmarkGoRestful_Param20(b *testing.B) { 612 | handler := loadGoRestfulSingle("GET", twentyBrace, goRestfulHandler) 613 | 614 | r, _ := http.NewRequest("GET", twentyRoute, nil) 615 | benchRequest(b, handler, r) 616 | } 617 | func BenchmarkGorillaMux_Param20(b *testing.B) { 618 | router := loadGorillaMuxSingle("GET", twentyBrace, httpHandlerFunc) 619 | 620 | r, _ := http.NewRequest("GET", twentyRoute, nil) 621 | benchRequest(b, router, r) 622 | } 623 | func BenchmarkGowwwRouter_Param20(b *testing.B) { 624 | router := loadGowwwRouterSingle("GET", twentyColon, http.HandlerFunc(httpHandlerFunc)) 625 | 626 | r, _ := http.NewRequest("GET", twentyRoute, nil) 627 | benchRequest(b, router, r) 628 | } 629 | func BenchmarkHttpRouter_Param20(b *testing.B) { 630 | router := loadHttpRouterSingle("GET", twentyColon, httpRouterHandle) 631 | 632 | r, _ := http.NewRequest("GET", twentyRoute, nil) 633 | benchRequest(b, router, r) 634 | } 635 | func BenchmarkHttpTreeMux_Param20(b *testing.B) { 636 | router := loadHttpTreeMuxSingle("GET", twentyColon, httpTreeMuxHandler) 637 | 638 | r, _ := http.NewRequest("GET", twentyRoute, nil) 639 | benchRequest(b, router, r) 640 | } 641 | func BenchmarkKocha_Param20(b *testing.B) { 642 | handler := new(kochaHandler) 643 | router := loadKochaSingle( 644 | "GET", twentyColon, 645 | handler, http.HandlerFunc(handler.Get), 646 | ) 647 | 648 | r, _ := http.NewRequest("GET", twentyRoute, nil) 649 | benchRequest(b, router, r) 650 | } 651 | func BenchmarkLARS_Param20(b *testing.B) { 652 | router := loadLARSSingle("GET", twentyColon, larsHandler) 653 | 654 | r, _ := http.NewRequest("GET", twentyRoute, nil) 655 | benchRequest(b, router, r) 656 | } 657 | func BenchmarkMacaron_Param20(b *testing.B) { 658 | router := loadMacaronSingle("GET", twentyColon, macaronHandler) 659 | 660 | r, _ := http.NewRequest("GET", twentyRoute, nil) 661 | benchRequest(b, router, r) 662 | } 663 | func BenchmarkMartini_Param20(b *testing.B) { 664 | router := loadMartiniSingle("GET", twentyColon, martiniHandler) 665 | 666 | r, _ := http.NewRequest("GET", twentyRoute, nil) 667 | benchRequest(b, router, r) 668 | } 669 | func BenchmarkPat_Param20(b *testing.B) { 670 | router := loadPatSingle("GET", twentyColon, http.HandlerFunc(httpHandlerFunc)) 671 | 672 | r, _ := http.NewRequest("GET", twentyRoute, nil) 673 | benchRequest(b, router, r) 674 | } 675 | func BenchmarkPossum_Param20(b *testing.B) { 676 | router := loadPossumSingle("GET", twentyColon, possumHandler) 677 | 678 | r, _ := http.NewRequest("GET", twentyRoute, nil) 679 | benchRequest(b, router, r) 680 | } 681 | func BenchmarkR2router_Param20(b *testing.B) { 682 | router := loadR2routerSingle("GET", twentyColon, r2routerHandler) 683 | 684 | r, _ := http.NewRequest("GET", twentyRoute, nil) 685 | benchRequest(b, router, r) 686 | } 687 | 688 | // func BenchmarkRevel_Param20(b *testing.B) { 689 | // router := loadRevelSingle("GET", twentyColon, "RevelController.Handle") 690 | 691 | // r, _ := http.NewRequest("GET", twentyRoute, nil) 692 | // benchRequest(b, router, r) 693 | // } 694 | func BenchmarkRivet_Param20(b *testing.B) { 695 | router := loadRivetSingle("GET", twentyColon, rivetHandler) 696 | 697 | r, _ := http.NewRequest("GET", twentyRoute, nil) 698 | benchRequest(b, router, r) 699 | } 700 | func BenchmarkTango_Param20(b *testing.B) { 701 | router := loadTangoSingle("GET", twentyColon, tangoHandler) 702 | 703 | r, _ := http.NewRequest("GET", twentyRoute, nil) 704 | benchRequest(b, router, r) 705 | } 706 | func BenchmarkTigerTonic_Param20(b *testing.B) { 707 | router := loadTigerTonicSingle("GET", twentyBrace, httpHandlerFunc) 708 | 709 | r, _ := http.NewRequest("GET", twentyRoute, nil) 710 | benchRequest(b, router, r) 711 | } 712 | func BenchmarkTraffic_Param20(b *testing.B) { 713 | router := loadTrafficSingle("GET", twentyColon, trafficHandler) 714 | 715 | r, _ := http.NewRequest("GET", twentyRoute, nil) 716 | benchRequest(b, router, r) 717 | } 718 | func BenchmarkVulcan_Param20(b *testing.B) { 719 | router := loadVulcanSingle("GET", twentyColon, vulcanHandler) 720 | 721 | r, _ := http.NewRequest("GET", twentyRoute, nil) 722 | benchRequest(b, router, r) 723 | } 724 | 725 | // func BenchmarkZeus_Param20(b *testing.B) { 726 | // router := loadZeusSingle("GET", twentyColon, http.HandlerFunc(httpHandlerFunc)) 727 | 728 | // r, _ := http.NewRequest("GET", twentyRoute, nil) 729 | // benchRequest(b, router, r) 730 | // } 731 | 732 | // Route with Param and write 733 | func BenchmarkAce_ParamWrite(b *testing.B) { 734 | router := loadAceSingle("GET", "/user/:name", aceHandleWrite) 735 | 736 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 737 | benchRequest(b, router, r) 738 | } 739 | func BenchmarkAero_ParamWrite(b *testing.B) { 740 | router := loadAeroSingle("GET", "/user/:name", aeroHandlerTest) 741 | 742 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 743 | benchRequest(b, router, r) 744 | } 745 | func BenchmarkBear_ParamWrite(b *testing.B) { 746 | router := loadBearSingle("GET", "/user/{name}", bearHandlerWrite) 747 | 748 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 749 | benchRequest(b, router, r) 750 | } 751 | func BenchmarkBeego_ParamWrite(b *testing.B) { 752 | router := loadBeegoSingle("GET", "/user/:name", beegoHandlerWrite) 753 | 754 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 755 | benchRequest(b, router, r) 756 | } 757 | func BenchmarkBone_ParamWrite(b *testing.B) { 758 | router := loadBoneSingle("GET", "/user/:name", http.HandlerFunc(boneHandlerWrite)) 759 | 760 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 761 | benchRequest(b, router, r) 762 | } 763 | func BenchmarkChi_ParamWrite(b *testing.B) { 764 | router := loadChiSingle("GET", "/user/{name}", chiHandleWrite) 765 | 766 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 767 | benchRequest(b, router, r) 768 | } 769 | func BenchmarkCloudyKitRouter_ParamWrite(b *testing.B) { 770 | router := loadCloudyKitRouterSingle("GET", "/user/:name", cloudyKitRouterHandler) 771 | 772 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 773 | benchRequest(b, router, r) 774 | } 775 | func BenchmarkDenco_ParamWrite(b *testing.B) { 776 | router := loadDencoSingle("GET", "/user/:name", dencoHandlerWrite) 777 | 778 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 779 | benchRequest(b, router, r) 780 | } 781 | func BenchmarkEcho_ParamWrite(b *testing.B) { 782 | router := loadEchoSingle("GET", "/user/:name", echoHandlerWrite) 783 | 784 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 785 | benchRequest(b, router, r) 786 | } 787 | func BenchmarkGin_ParamWrite(b *testing.B) { 788 | router := loadGinSingle("GET", "/user/:name", ginHandleWrite) 789 | 790 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 791 | benchRequest(b, router, r) 792 | } 793 | func BenchmarkGocraftWeb_ParamWrite(b *testing.B) { 794 | router := loadGocraftWebSingle("GET", "/user/:name", gocraftWebHandlerWrite) 795 | 796 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 797 | benchRequest(b, router, r) 798 | } 799 | func BenchmarkGoji_ParamWrite(b *testing.B) { 800 | router := loadGojiSingle("GET", "/user/:name", gojiFuncWrite) 801 | 802 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 803 | benchRequest(b, router, r) 804 | } 805 | func BenchmarkGojiv2_ParamWrite(b *testing.B) { 806 | router := loadGojiv2Single("GET", "/user/:name", gojiv2HandlerWrite) 807 | 808 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 809 | benchRequest(b, router, r) 810 | } 811 | func BenchmarkGoJsonRest_ParamWrite(b *testing.B) { 812 | handler := loadGoJsonRestSingle("GET", "/user/:name", goJsonRestHandlerWrite) 813 | 814 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 815 | benchRequest(b, handler, r) 816 | } 817 | func BenchmarkGoRestful_ParamWrite(b *testing.B) { 818 | handler := loadGoRestfulSingle("GET", "/user/{name}", goRestfulHandlerWrite) 819 | 820 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 821 | benchRequest(b, handler, r) 822 | } 823 | func BenchmarkGorillaMux_ParamWrite(b *testing.B) { 824 | router := loadGorillaMuxSingle("GET", "/user/{name}", gorillaHandlerWrite) 825 | 826 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 827 | benchRequest(b, router, r) 828 | } 829 | func BenchmarkGowwwRouter_ParamWrite(b *testing.B) { 830 | router := loadGowwwRouterSingle("GET", "/user/:name", http.HandlerFunc(gowwwRouterHandleWrite)) 831 | 832 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 833 | benchRequest(b, router, r) 834 | } 835 | func BenchmarkHttpRouter_ParamWrite(b *testing.B) { 836 | router := loadHttpRouterSingle("GET", "/user/:name", httpRouterHandleWrite) 837 | 838 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 839 | benchRequest(b, router, r) 840 | } 841 | func BenchmarkHttpTreeMux_ParamWrite(b *testing.B) { 842 | router := loadHttpTreeMuxSingle("GET", "/user/:name", httpTreeMuxHandlerWrite) 843 | 844 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 845 | benchRequest(b, router, r) 846 | } 847 | func BenchmarkKocha_ParamWrite(b *testing.B) { 848 | handler := new(kochaHandler) 849 | router := loadKochaSingle( 850 | "GET", "/user/:name", 851 | handler, http.HandlerFunc(handler.kochaHandlerWrite), 852 | ) 853 | 854 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 855 | benchRequest(b, router, r) 856 | } 857 | func BenchmarkLARS_ParamWrite(b *testing.B) { 858 | router := loadLARSSingle("GET", "/user/:name", larsHandlerWrite) 859 | 860 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 861 | benchRequest(b, router, r) 862 | } 863 | func BenchmarkMacaron_ParamWrite(b *testing.B) { 864 | router := loadMacaronSingle("GET", "/user/:name", macaronHandlerWrite) 865 | 866 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 867 | benchRequest(b, router, r) 868 | } 869 | func BenchmarkMartini_ParamWrite(b *testing.B) { 870 | router := loadMartiniSingle("GET", "/user/:name", martiniHandlerWrite) 871 | 872 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 873 | benchRequest(b, router, r) 874 | } 875 | func BenchmarkPat_ParamWrite(b *testing.B) { 876 | router := loadPatSingle("GET", "/user/:name", http.HandlerFunc(patHandlerWrite)) 877 | 878 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 879 | benchRequest(b, router, r) 880 | } 881 | func BenchmarkPossum_ParamWrite(b *testing.B) { 882 | router := loadPossumSingle("GET", "/user/:name", possumHandlerWrite) 883 | 884 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 885 | benchRequest(b, router, r) 886 | } 887 | func BenchmarkR2router_ParamWrite(b *testing.B) { 888 | router := loadR2routerSingle("GET", "/user/:name", r2routerHandleWrite) 889 | 890 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 891 | benchRequest(b, router, r) 892 | } 893 | 894 | // func BenchmarkRevel_ParamWrite(b *testing.B) { 895 | // router := loadRevelSingle("GET", "/user/:name", "RevelController.HandleWrite") 896 | 897 | // r, _ := http.NewRequest("GET", "/user/gordon", nil) 898 | // benchRequest(b, router, r) 899 | // } 900 | func BenchmarkRivet_ParamWrite(b *testing.B) { 901 | router := loadRivetSingle("GET", "/user/:name", rivetHandlerWrite) 902 | 903 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 904 | benchRequest(b, router, r) 905 | } 906 | func BenchmarkTango_ParamWrite(b *testing.B) { 907 | router := loadTangoSingle("GET", "/user/:name", tangoHandlerWrite) 908 | 909 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 910 | benchRequest(b, router, r) 911 | } 912 | func BenchmarkTigerTonic_ParamWrite(b *testing.B) { 913 | router := loadTigerTonicSingle( 914 | "GET", "/user/{name}", 915 | http.HandlerFunc(tigerTonicHandlerWrite), 916 | ) 917 | 918 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 919 | benchRequest(b, router, r) 920 | } 921 | func BenchmarkTraffic_ParamWrite(b *testing.B) { 922 | router := loadTrafficSingle("GET", "/user/:name", trafficHandlerWrite) 923 | 924 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 925 | benchRequest(b, router, r) 926 | } 927 | func BenchmarkVulcan_ParamWrite(b *testing.B) { 928 | router := loadVulcanSingle("GET", "/user/:name", vulcanHandlerWrite) 929 | 930 | r, _ := http.NewRequest("GET", "/user/gordon", nil) 931 | benchRequest(b, router, r) 932 | } 933 | 934 | // func BenchmarkZeus_ParamWrite(b *testing.B) { 935 | // router := loadZeusSingle("GET", "/user/:name", zeusHandlerWrite) 936 | 937 | // r, _ := http.NewRequest("GET", "/user/gordon", nil) 938 | // benchRequest(b, router, r) 939 | // } 940 | -------------------------------------------------------------------------------- /conf/app.conf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/julienschmidt/go-http-routing-benchmark/d8f3b858995830fc29e26206d7d4d97ece34528c/conf/app.conf -------------------------------------------------------------------------------- /github_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Julien Schmidt. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be found 3 | // in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "net/http" 9 | "testing" 10 | ) 11 | 12 | // http://developer.github.com/v3/ 13 | var githubAPI = []route{ 14 | // OAuth Authorizations 15 | {"GET", "/authorizations"}, 16 | {"GET", "/authorizations/:id"}, 17 | {"POST", "/authorizations"}, 18 | //{"PUT", "/authorizations/clients/:client_id"}, 19 | //{"PATCH", "/authorizations/:id"}, 20 | {"DELETE", "/authorizations/:id"}, 21 | {"GET", "/applications/:client_id/tokens/:access_token"}, 22 | {"DELETE", "/applications/:client_id/tokens"}, 23 | {"DELETE", "/applications/:client_id/tokens/:access_token"}, 24 | 25 | // Activity 26 | {"GET", "/events"}, 27 | {"GET", "/repos/:owner/:repo/events"}, 28 | {"GET", "/networks/:owner/:repo/events"}, 29 | {"GET", "/orgs/:org/events"}, 30 | {"GET", "/users/:user/received_events"}, 31 | {"GET", "/users/:user/received_events/public"}, 32 | {"GET", "/users/:user/events"}, 33 | {"GET", "/users/:user/events/public"}, 34 | {"GET", "/users/:user/events/orgs/:org"}, 35 | {"GET", "/feeds"}, 36 | {"GET", "/notifications"}, 37 | {"GET", "/repos/:owner/:repo/notifications"}, 38 | {"PUT", "/notifications"}, 39 | {"PUT", "/repos/:owner/:repo/notifications"}, 40 | {"GET", "/notifications/threads/:id"}, 41 | //{"PATCH", "/notifications/threads/:id"}, 42 | {"GET", "/notifications/threads/:id/subscription"}, 43 | {"PUT", "/notifications/threads/:id/subscription"}, 44 | {"DELETE", "/notifications/threads/:id/subscription"}, 45 | {"GET", "/repos/:owner/:repo/stargazers"}, 46 | {"GET", "/users/:user/starred"}, 47 | {"GET", "/user/starred"}, 48 | {"GET", "/user/starred/:owner/:repo"}, 49 | {"PUT", "/user/starred/:owner/:repo"}, 50 | {"DELETE", "/user/starred/:owner/:repo"}, 51 | {"GET", "/repos/:owner/:repo/subscribers"}, 52 | {"GET", "/users/:user/subscriptions"}, 53 | {"GET", "/user/subscriptions"}, 54 | {"GET", "/repos/:owner/:repo/subscription"}, 55 | {"PUT", "/repos/:owner/:repo/subscription"}, 56 | {"DELETE", "/repos/:owner/:repo/subscription"}, 57 | {"GET", "/user/subscriptions/:owner/:repo"}, 58 | {"PUT", "/user/subscriptions/:owner/:repo"}, 59 | {"DELETE", "/user/subscriptions/:owner/:repo"}, 60 | 61 | // Gists 62 | {"GET", "/users/:user/gists"}, 63 | {"GET", "/gists"}, 64 | //{"GET", "/gists/public"}, 65 | //{"GET", "/gists/starred"}, 66 | {"GET", "/gists/:id"}, 67 | {"POST", "/gists"}, 68 | //{"PATCH", "/gists/:id"}, 69 | {"PUT", "/gists/:id/star"}, 70 | {"DELETE", "/gists/:id/star"}, 71 | {"GET", "/gists/:id/star"}, 72 | {"POST", "/gists/:id/forks"}, 73 | {"DELETE", "/gists/:id"}, 74 | 75 | // Git Data 76 | {"GET", "/repos/:owner/:repo/git/blobs/:sha"}, 77 | {"POST", "/repos/:owner/:repo/git/blobs"}, 78 | {"GET", "/repos/:owner/:repo/git/commits/:sha"}, 79 | {"POST", "/repos/:owner/:repo/git/commits"}, 80 | //{"GET", "/repos/:owner/:repo/git/refs/*ref"}, 81 | {"GET", "/repos/:owner/:repo/git/refs"}, 82 | {"POST", "/repos/:owner/:repo/git/refs"}, 83 | //{"PATCH", "/repos/:owner/:repo/git/refs/*ref"}, 84 | //{"DELETE", "/repos/:owner/:repo/git/refs/*ref"}, 85 | {"GET", "/repos/:owner/:repo/git/tags/:sha"}, 86 | {"POST", "/repos/:owner/:repo/git/tags"}, 87 | {"GET", "/repos/:owner/:repo/git/trees/:sha"}, 88 | {"POST", "/repos/:owner/:repo/git/trees"}, 89 | 90 | // Issues 91 | {"GET", "/issues"}, 92 | {"GET", "/user/issues"}, 93 | {"GET", "/orgs/:org/issues"}, 94 | {"GET", "/repos/:owner/:repo/issues"}, 95 | {"GET", "/repos/:owner/:repo/issues/:number"}, 96 | {"POST", "/repos/:owner/:repo/issues"}, 97 | //{"PATCH", "/repos/:owner/:repo/issues/:number"}, 98 | {"GET", "/repos/:owner/:repo/assignees"}, 99 | {"GET", "/repos/:owner/:repo/assignees/:assignee"}, 100 | {"GET", "/repos/:owner/:repo/issues/:number/comments"}, 101 | //{"GET", "/repos/:owner/:repo/issues/comments"}, 102 | //{"GET", "/repos/:owner/:repo/issues/comments/:id"}, 103 | {"POST", "/repos/:owner/:repo/issues/:number/comments"}, 104 | //{"PATCH", "/repos/:owner/:repo/issues/comments/:id"}, 105 | //{"DELETE", "/repos/:owner/:repo/issues/comments/:id"}, 106 | {"GET", "/repos/:owner/:repo/issues/:number/events"}, 107 | //{"GET", "/repos/:owner/:repo/issues/events"}, 108 | //{"GET", "/repos/:owner/:repo/issues/events/:id"}, 109 | {"GET", "/repos/:owner/:repo/labels"}, 110 | {"GET", "/repos/:owner/:repo/labels/:name"}, 111 | {"POST", "/repos/:owner/:repo/labels"}, 112 | //{"PATCH", "/repos/:owner/:repo/labels/:name"}, 113 | {"DELETE", "/repos/:owner/:repo/labels/:name"}, 114 | {"GET", "/repos/:owner/:repo/issues/:number/labels"}, 115 | {"POST", "/repos/:owner/:repo/issues/:number/labels"}, 116 | {"DELETE", "/repos/:owner/:repo/issues/:number/labels/:name"}, 117 | {"PUT", "/repos/:owner/:repo/issues/:number/labels"}, 118 | {"DELETE", "/repos/:owner/:repo/issues/:number/labels"}, 119 | {"GET", "/repos/:owner/:repo/milestones/:number/labels"}, 120 | {"GET", "/repos/:owner/:repo/milestones"}, 121 | {"GET", "/repos/:owner/:repo/milestones/:number"}, 122 | {"POST", "/repos/:owner/:repo/milestones"}, 123 | //{"PATCH", "/repos/:owner/:repo/milestones/:number"}, 124 | {"DELETE", "/repos/:owner/:repo/milestones/:number"}, 125 | 126 | // Miscellaneous 127 | {"GET", "/emojis"}, 128 | {"GET", "/gitignore/templates"}, 129 | {"GET", "/gitignore/templates/:name"}, 130 | {"POST", "/markdown"}, 131 | {"POST", "/markdown/raw"}, 132 | {"GET", "/meta"}, 133 | {"GET", "/rate_limit"}, 134 | 135 | // Organizations 136 | {"GET", "/users/:user/orgs"}, 137 | {"GET", "/user/orgs"}, 138 | {"GET", "/orgs/:org"}, 139 | //{"PATCH", "/orgs/:org"}, 140 | {"GET", "/orgs/:org/members"}, 141 | {"GET", "/orgs/:org/members/:user"}, 142 | {"DELETE", "/orgs/:org/members/:user"}, 143 | {"GET", "/orgs/:org/public_members"}, 144 | {"GET", "/orgs/:org/public_members/:user"}, 145 | {"PUT", "/orgs/:org/public_members/:user"}, 146 | {"DELETE", "/orgs/:org/public_members/:user"}, 147 | {"GET", "/orgs/:org/teams"}, 148 | {"GET", "/teams/:id"}, 149 | {"POST", "/orgs/:org/teams"}, 150 | //{"PATCH", "/teams/:id"}, 151 | {"DELETE", "/teams/:id"}, 152 | {"GET", "/teams/:id/members"}, 153 | {"GET", "/teams/:id/members/:user"}, 154 | {"PUT", "/teams/:id/members/:user"}, 155 | {"DELETE", "/teams/:id/members/:user"}, 156 | {"GET", "/teams/:id/repos"}, 157 | {"GET", "/teams/:id/repos/:owner/:repo"}, 158 | {"PUT", "/teams/:id/repos/:owner/:repo"}, 159 | {"DELETE", "/teams/:id/repos/:owner/:repo"}, 160 | {"GET", "/user/teams"}, 161 | 162 | // Pull Requests 163 | {"GET", "/repos/:owner/:repo/pulls"}, 164 | {"GET", "/repos/:owner/:repo/pulls/:number"}, 165 | {"POST", "/repos/:owner/:repo/pulls"}, 166 | //{"PATCH", "/repos/:owner/:repo/pulls/:number"}, 167 | {"GET", "/repos/:owner/:repo/pulls/:number/commits"}, 168 | {"GET", "/repos/:owner/:repo/pulls/:number/files"}, 169 | {"GET", "/repos/:owner/:repo/pulls/:number/merge"}, 170 | {"PUT", "/repos/:owner/:repo/pulls/:number/merge"}, 171 | {"GET", "/repos/:owner/:repo/pulls/:number/comments"}, 172 | //{"GET", "/repos/:owner/:repo/pulls/comments"}, 173 | //{"GET", "/repos/:owner/:repo/pulls/comments/:number"}, 174 | {"PUT", "/repos/:owner/:repo/pulls/:number/comments"}, 175 | //{"PATCH", "/repos/:owner/:repo/pulls/comments/:number"}, 176 | //{"DELETE", "/repos/:owner/:repo/pulls/comments/:number"}, 177 | 178 | // Repositories 179 | {"GET", "/user/repos"}, 180 | {"GET", "/users/:user/repos"}, 181 | {"GET", "/orgs/:org/repos"}, 182 | {"GET", "/repositories"}, 183 | {"POST", "/user/repos"}, 184 | {"POST", "/orgs/:org/repos"}, 185 | {"GET", "/repos/:owner/:repo"}, 186 | //{"PATCH", "/repos/:owner/:repo"}, 187 | {"GET", "/repos/:owner/:repo/contributors"}, 188 | {"GET", "/repos/:owner/:repo/languages"}, 189 | {"GET", "/repos/:owner/:repo/teams"}, 190 | {"GET", "/repos/:owner/:repo/tags"}, 191 | {"GET", "/repos/:owner/:repo/branches"}, 192 | {"GET", "/repos/:owner/:repo/branches/:branch"}, 193 | {"DELETE", "/repos/:owner/:repo"}, 194 | {"GET", "/repos/:owner/:repo/collaborators"}, 195 | {"GET", "/repos/:owner/:repo/collaborators/:user"}, 196 | {"PUT", "/repos/:owner/:repo/collaborators/:user"}, 197 | {"DELETE", "/repos/:owner/:repo/collaborators/:user"}, 198 | {"GET", "/repos/:owner/:repo/comments"}, 199 | {"GET", "/repos/:owner/:repo/commits/:sha/comments"}, 200 | {"POST", "/repos/:owner/:repo/commits/:sha/comments"}, 201 | {"GET", "/repos/:owner/:repo/comments/:id"}, 202 | //{"PATCH", "/repos/:owner/:repo/comments/:id"}, 203 | {"DELETE", "/repos/:owner/:repo/comments/:id"}, 204 | {"GET", "/repos/:owner/:repo/commits"}, 205 | {"GET", "/repos/:owner/:repo/commits/:sha"}, 206 | {"GET", "/repos/:owner/:repo/readme"}, 207 | //{"GET", "/repos/:owner/:repo/contents/*path"}, 208 | //{"PUT", "/repos/:owner/:repo/contents/*path"}, 209 | //{"DELETE", "/repos/:owner/:repo/contents/*path"}, 210 | //{"GET", "/repos/:owner/:repo/:archive_format/:ref"}, 211 | {"GET", "/repos/:owner/:repo/keys"}, 212 | {"GET", "/repos/:owner/:repo/keys/:id"}, 213 | {"POST", "/repos/:owner/:repo/keys"}, 214 | //{"PATCH", "/repos/:owner/:repo/keys/:id"}, 215 | {"DELETE", "/repos/:owner/:repo/keys/:id"}, 216 | {"GET", "/repos/:owner/:repo/downloads"}, 217 | {"GET", "/repos/:owner/:repo/downloads/:id"}, 218 | {"DELETE", "/repos/:owner/:repo/downloads/:id"}, 219 | {"GET", "/repos/:owner/:repo/forks"}, 220 | {"POST", "/repos/:owner/:repo/forks"}, 221 | {"GET", "/repos/:owner/:repo/hooks"}, 222 | {"GET", "/repos/:owner/:repo/hooks/:id"}, 223 | {"POST", "/repos/:owner/:repo/hooks"}, 224 | //{"PATCH", "/repos/:owner/:repo/hooks/:id"}, 225 | {"POST", "/repos/:owner/:repo/hooks/:id/tests"}, 226 | {"DELETE", "/repos/:owner/:repo/hooks/:id"}, 227 | {"POST", "/repos/:owner/:repo/merges"}, 228 | {"GET", "/repos/:owner/:repo/releases"}, 229 | {"GET", "/repos/:owner/:repo/releases/:id"}, 230 | {"POST", "/repos/:owner/:repo/releases"}, 231 | //{"PATCH", "/repos/:owner/:repo/releases/:id"}, 232 | {"DELETE", "/repos/:owner/:repo/releases/:id"}, 233 | {"GET", "/repos/:owner/:repo/releases/:id/assets"}, 234 | {"GET", "/repos/:owner/:repo/stats/contributors"}, 235 | {"GET", "/repos/:owner/:repo/stats/commit_activity"}, 236 | {"GET", "/repos/:owner/:repo/stats/code_frequency"}, 237 | {"GET", "/repos/:owner/:repo/stats/participation"}, 238 | {"GET", "/repos/:owner/:repo/stats/punch_card"}, 239 | {"GET", "/repos/:owner/:repo/statuses/:ref"}, 240 | {"POST", "/repos/:owner/:repo/statuses/:ref"}, 241 | 242 | // Search 243 | {"GET", "/search/repositories"}, 244 | {"GET", "/search/code"}, 245 | {"GET", "/search/issues"}, 246 | {"GET", "/search/users"}, 247 | {"GET", "/legacy/issues/search/:owner/:repository/:state/:keyword"}, 248 | {"GET", "/legacy/repos/search/:keyword"}, 249 | {"GET", "/legacy/user/search/:keyword"}, 250 | {"GET", "/legacy/user/email/:email"}, 251 | 252 | // Users 253 | {"GET", "/users/:user"}, 254 | {"GET", "/user"}, 255 | //{"PATCH", "/user"}, 256 | {"GET", "/users"}, 257 | {"GET", "/user/emails"}, 258 | {"POST", "/user/emails"}, 259 | {"DELETE", "/user/emails"}, 260 | {"GET", "/users/:user/followers"}, 261 | {"GET", "/user/followers"}, 262 | {"GET", "/users/:user/following"}, 263 | {"GET", "/user/following"}, 264 | {"GET", "/user/following/:user"}, 265 | {"GET", "/users/:user/following/:target_user"}, 266 | {"PUT", "/user/following/:user"}, 267 | {"DELETE", "/user/following/:user"}, 268 | {"GET", "/users/:user/keys"}, 269 | {"GET", "/user/keys"}, 270 | {"GET", "/user/keys/:id"}, 271 | {"POST", "/user/keys"}, 272 | //{"PATCH", "/user/keys/:id"}, 273 | {"DELETE", "/user/keys/:id"}, 274 | } 275 | 276 | var ( 277 | githubAce http.Handler 278 | githubAero http.Handler 279 | githubBear http.Handler 280 | githubBeego http.Handler 281 | githubBone http.Handler 282 | githubChi http.Handler 283 | githubCloudyKitRouter http.Handler 284 | githubDenco http.Handler 285 | githubEcho http.Handler 286 | githubGin http.Handler 287 | githubGocraftWeb http.Handler 288 | githubGoji http.Handler 289 | githubGojiv2 http.Handler 290 | githubGoJsonRest http.Handler 291 | githubGoRestful http.Handler 292 | githubGorillaMux http.Handler 293 | githubGowwwRouter http.Handler 294 | githubHttpRouter http.Handler 295 | githubHttpTreeMux http.Handler 296 | githubKocha http.Handler 297 | githubLARS http.Handler 298 | githubMacaron http.Handler 299 | githubMartini http.Handler 300 | githubPat http.Handler 301 | githubPossum http.Handler 302 | githubR2router http.Handler 303 | githubRevel http.Handler 304 | githubRivet http.Handler 305 | githubTango http.Handler 306 | githubTigerTonic http.Handler 307 | githubTraffic http.Handler 308 | githubVulcan http.Handler 309 | // githubZeus http.Handler 310 | ) 311 | 312 | func init() { 313 | println("#GithubAPI Routes:", len(githubAPI)) 314 | 315 | calcMem("Ace", func() { 316 | githubAce = loadAce(githubAPI) 317 | }) 318 | calcMem("Aero", func() { 319 | githubAero = loadAero(githubAPI) 320 | }) 321 | calcMem("Bear", func() { 322 | githubBear = loadBear(githubAPI) 323 | }) 324 | calcMem("Beego", func() { 325 | githubBeego = loadBeego(githubAPI) 326 | }) 327 | calcMem("Bone", func() { 328 | githubBone = loadBone(githubAPI) 329 | }) 330 | calcMem("Chi", func() { 331 | githubChi = loadChi(githubAPI) 332 | }) 333 | calcMem("CloudyKitRouter", func() { 334 | githubCloudyKitRouter = loadCloudyKitRouter(githubAPI) 335 | }) 336 | calcMem("Denco", func() { 337 | githubDenco = loadDenco(githubAPI) 338 | }) 339 | calcMem("Echo", func() { 340 | githubEcho = loadEcho(githubAPI) 341 | }) 342 | calcMem("Gin", func() { 343 | githubGin = loadGin(githubAPI) 344 | }) 345 | calcMem("GocraftWeb", func() { 346 | githubGocraftWeb = loadGocraftWeb(githubAPI) 347 | }) 348 | calcMem("Goji", func() { 349 | githubGoji = loadGoji(githubAPI) 350 | }) 351 | calcMem("Gojiv2", func() { 352 | githubGojiv2 = loadGojiv2(githubAPI) 353 | }) 354 | calcMem("GoJsonRest", func() { 355 | githubGoJsonRest = loadGoJsonRest(githubAPI) 356 | }) 357 | calcMem("GoRestful", func() { 358 | githubGoRestful = loadGoRestful(githubAPI) 359 | }) 360 | calcMem("GorillaMux", func() { 361 | githubGorillaMux = loadGorillaMux(githubAPI) 362 | }) 363 | calcMem("GowwwRouter", func() { 364 | githubGowwwRouter = loadGowwwRouter(githubAPI) 365 | }) 366 | calcMem("HttpRouter", func() { 367 | githubHttpRouter = loadHttpRouter(githubAPI) 368 | }) 369 | calcMem("HttpTreeMux", func() { 370 | githubHttpTreeMux = loadHttpTreeMux(githubAPI) 371 | }) 372 | calcMem("Kocha", func() { 373 | githubKocha = loadKocha(githubAPI) 374 | }) 375 | calcMem("LARS", func() { 376 | githubLARS = loadLARS(githubAPI) 377 | }) 378 | calcMem("Macaron", func() { 379 | githubMacaron = loadMacaron(githubAPI) 380 | }) 381 | calcMem("Martini", func() { 382 | githubMartini = loadMartini(githubAPI) 383 | }) 384 | calcMem("Pat", func() { 385 | githubPat = loadPat(githubAPI) 386 | }) 387 | calcMem("Possum", func() { 388 | githubPossum = loadPossum(githubAPI) 389 | }) 390 | calcMem("R2router", func() { 391 | githubR2router = loadR2router(githubAPI) 392 | }) 393 | // calcMem("Revel", func() { 394 | // githubRevel = loadRevel(githubAPI) 395 | // }) 396 | calcMem("Rivet", func() { 397 | githubRivet = loadRivet(githubAPI) 398 | }) 399 | calcMem("Tango", func() { 400 | githubTango = loadTango(githubAPI) 401 | }) 402 | calcMem("TigerTonic", func() { 403 | githubTigerTonic = loadTigerTonic(githubAPI) 404 | }) 405 | calcMem("Traffic", func() { 406 | githubTraffic = loadTraffic(githubAPI) 407 | }) 408 | calcMem("Vulcan", func() { 409 | githubVulcan = loadVulcan(githubAPI) 410 | }) 411 | // calcMem("Zeus", func() { 412 | // githubZeus = loadZeus(githubAPI) 413 | // }) 414 | 415 | println() 416 | } 417 | 418 | // Static 419 | func BenchmarkAce_GithubStatic(b *testing.B) { 420 | req, _ := http.NewRequest("GET", "/user/repos", nil) 421 | benchRequest(b, githubAce, req) 422 | } 423 | func BenchmarkAero_GithubStatic(b *testing.B) { 424 | req, _ := http.NewRequest("GET", "/user/repos", nil) 425 | benchRequest(b, githubAero, req) 426 | } 427 | func BenchmarkBear_GithubStatic(b *testing.B) { 428 | req, _ := http.NewRequest("GET", "/user/repos", nil) 429 | benchRequest(b, githubBear, req) 430 | } 431 | func BenchmarkBeego_GithubStatic(b *testing.B) { 432 | req, _ := http.NewRequest("GET", "/user/repos", nil) 433 | benchRequest(b, githubBeego, req) 434 | } 435 | func BenchmarkBone_GithubStatic(b *testing.B) { 436 | req, _ := http.NewRequest("GET", "/user/repos", nil) 437 | benchRequest(b, githubBone, req) 438 | } 439 | func BenchmarkCloudyKitRouter_GithubStatic(b *testing.B) { 440 | req, _ := http.NewRequest("GET", "/user/repos", nil) 441 | benchRequest(b, githubCloudyKitRouter, req) 442 | } 443 | func BenchmarkChi_GithubStatic(b *testing.B) { 444 | req, _ := http.NewRequest("GET", "/user/repos", nil) 445 | benchRequest(b, githubChi, req) 446 | } 447 | func BenchmarkDenco_GithubStatic(b *testing.B) { 448 | req, _ := http.NewRequest("GET", "/user/repos", nil) 449 | benchRequest(b, githubDenco, req) 450 | } 451 | func BenchmarkEcho_GithubStatic(b *testing.B) { 452 | req, _ := http.NewRequest("GET", "/user/repos", nil) 453 | benchRequest(b, githubEcho, req) 454 | } 455 | func BenchmarkGin_GithubStatic(b *testing.B) { 456 | req, _ := http.NewRequest("GET", "/user/repos", nil) 457 | benchRequest(b, githubGin, req) 458 | } 459 | func BenchmarkGocraftWeb_GithubStatic(b *testing.B) { 460 | req, _ := http.NewRequest("GET", "/user/repos", nil) 461 | benchRequest(b, githubGocraftWeb, req) 462 | } 463 | func BenchmarkGoji_GithubStatic(b *testing.B) { 464 | req, _ := http.NewRequest("GET", "/user/repos", nil) 465 | benchRequest(b, githubGoji, req) 466 | } 467 | func BenchmarkGojiv2_GithubStatic(b *testing.B) { 468 | req, _ := http.NewRequest("GET", "/user/repos", nil) 469 | benchRequest(b, githubGojiv2, req) 470 | } 471 | func BenchmarkGoRestful_GithubStatic(b *testing.B) { 472 | req, _ := http.NewRequest("GET", "/user/repos", nil) 473 | benchRequest(b, githubGoRestful, req) 474 | } 475 | func BenchmarkGoJsonRest_GithubStatic(b *testing.B) { 476 | req, _ := http.NewRequest("GET", "/user/repos", nil) 477 | benchRequest(b, githubGoJsonRest, req) 478 | } 479 | func BenchmarkGorillaMux_GithubStatic(b *testing.B) { 480 | req, _ := http.NewRequest("GET", "/user/repos", nil) 481 | benchRequest(b, githubGorillaMux, req) 482 | } 483 | func BenchmarkGowwwRouter_GithubStatic(b *testing.B) { 484 | req, _ := http.NewRequest("GET", "/user/repos", nil) 485 | benchRequest(b, githubGowwwRouter, req) 486 | } 487 | func BenchmarkHttpRouter_GithubStatic(b *testing.B) { 488 | req, _ := http.NewRequest("GET", "/user/repos", nil) 489 | benchRequest(b, githubHttpRouter, req) 490 | } 491 | func BenchmarkHttpTreeMux_GithubStatic(b *testing.B) { 492 | req, _ := http.NewRequest("GET", "/user/repos", nil) 493 | benchRequest(b, githubHttpTreeMux, req) 494 | } 495 | func BenchmarkKocha_GithubStatic(b *testing.B) { 496 | req, _ := http.NewRequest("GET", "/user/repos", nil) 497 | benchRequest(b, githubKocha, req) 498 | } 499 | func BenchmarkLARS_GithubStatic(b *testing.B) { 500 | req, _ := http.NewRequest("GET", "/user/repos", nil) 501 | benchRequest(b, githubLARS, req) 502 | } 503 | func BenchmarkMacaron_GithubStatic(b *testing.B) { 504 | req, _ := http.NewRequest("GET", "/user/repos", nil) 505 | benchRequest(b, githubMacaron, req) 506 | } 507 | func BenchmarkMartini_GithubStatic(b *testing.B) { 508 | req, _ := http.NewRequest("GET", "/user/repos", nil) 509 | benchRequest(b, githubMartini, req) 510 | } 511 | func BenchmarkPat_GithubStatic(b *testing.B) { 512 | req, _ := http.NewRequest("GET", "/user/repos", nil) 513 | benchRequest(b, githubPat, req) 514 | } 515 | func BenchmarkPossum_GithubStatic(b *testing.B) { 516 | req, _ := http.NewRequest("GET", "/user/repos", nil) 517 | benchRequest(b, githubPossum, req) 518 | } 519 | func BenchmarkR2router_GithubStatic(b *testing.B) { 520 | req, _ := http.NewRequest("GET", "/user/repos", nil) 521 | benchRequest(b, githubR2router, req) 522 | } 523 | 524 | // func BenchmarkRevel_GithubStatic(b *testing.B) { 525 | // req, _ := http.NewRequest("GET", "/user/repos", nil) 526 | // benchRequest(b, githubRevel, req) 527 | // } 528 | func BenchmarkRivet_GithubStatic(b *testing.B) { 529 | req, _ := http.NewRequest("GET", "/user/repos", nil) 530 | benchRequest(b, githubRivet, req) 531 | } 532 | func BenchmarkTango_GithubStatic(b *testing.B) { 533 | req, _ := http.NewRequest("GET", "/user/repos", nil) 534 | benchRequest(b, githubTango, req) 535 | } 536 | func BenchmarkTigerTonic_GithubStatic(b *testing.B) { 537 | req, _ := http.NewRequest("GET", "/user/repos", nil) 538 | benchRequest(b, githubTigerTonic, req) 539 | } 540 | func BenchmarkTraffic_GithubStatic(b *testing.B) { 541 | req, _ := http.NewRequest("GET", "/user/repos", nil) 542 | benchRequest(b, githubTraffic, req) 543 | } 544 | func BenchmarkVulcan_GithubStatic(b *testing.B) { 545 | req, _ := http.NewRequest("GET", "/user/repos", nil) 546 | benchRequest(b, githubVulcan, req) 547 | } 548 | 549 | // func BenchmarkZeus_GithubStatic(b *testing.B) { 550 | // req, _ := http.NewRequest("GET", "/user/repos", nil) 551 | // benchRequest(b, githubZeus, req) 552 | // } 553 | 554 | // Param 555 | func BenchmarkAce_GithubParam(b *testing.B) { 556 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 557 | benchRequest(b, githubAce, req) 558 | } 559 | func BenchmarkAero_GithubParam(b *testing.B) { 560 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 561 | benchRequest(b, githubAero, req) 562 | } 563 | func BenchmarkBear_GithubParam(b *testing.B) { 564 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 565 | benchRequest(b, githubBear, req) 566 | } 567 | func BenchmarkBeego_GithubParam(b *testing.B) { 568 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 569 | benchRequest(b, githubBeego, req) 570 | } 571 | func BenchmarkBone_GithubParam(b *testing.B) { 572 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 573 | benchRequest(b, githubBone, req) 574 | } 575 | func BenchmarkChi_GithubParam(b *testing.B) { 576 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 577 | benchRequest(b, githubChi, req) 578 | } 579 | func BenchmarkCloudyKitRouter_GithubParam(b *testing.B) { 580 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 581 | benchRequest(b, githubCloudyKitRouter, req) 582 | } 583 | func BenchmarkDenco_GithubParam(b *testing.B) { 584 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 585 | benchRequest(b, githubDenco, req) 586 | } 587 | func BenchmarkEcho_GithubParam(b *testing.B) { 588 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 589 | benchRequest(b, githubEcho, req) 590 | } 591 | func BenchmarkGin_GithubParam(b *testing.B) { 592 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 593 | benchRequest(b, githubGin, req) 594 | } 595 | func BenchmarkGocraftWeb_GithubParam(b *testing.B) { 596 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 597 | benchRequest(b, githubGocraftWeb, req) 598 | } 599 | func BenchmarkGoji_GithubParam(b *testing.B) { 600 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 601 | benchRequest(b, githubGoji, req) 602 | } 603 | func BenchmarkGojiv2_GithubParam(b *testing.B) { 604 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 605 | benchRequest(b, githubGojiv2, req) 606 | } 607 | func BenchmarkGoJsonRest_GithubParam(b *testing.B) { 608 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 609 | benchRequest(b, githubGoJsonRest, req) 610 | } 611 | func BenchmarkGoRestful_GithubParam(b *testing.B) { 612 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 613 | benchRequest(b, githubGoRestful, req) 614 | } 615 | func BenchmarkGorillaMux_GithubParam(b *testing.B) { 616 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 617 | benchRequest(b, githubGorillaMux, req) 618 | } 619 | func BenchmarkGowwwRouter_GithubParam(b *testing.B) { 620 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 621 | benchRequest(b, githubGowwwRouter, req) 622 | } 623 | func BenchmarkHttpRouter_GithubParam(b *testing.B) { 624 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 625 | benchRequest(b, githubHttpRouter, req) 626 | } 627 | func BenchmarkHttpTreeMux_GithubParam(b *testing.B) { 628 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 629 | benchRequest(b, githubHttpTreeMux, req) 630 | } 631 | func BenchmarkKocha_GithubParam(b *testing.B) { 632 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 633 | benchRequest(b, githubKocha, req) 634 | } 635 | func BenchmarkLARS_GithubParam(b *testing.B) { 636 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 637 | benchRequest(b, githubLARS, req) 638 | } 639 | func BenchmarkMacaron_GithubParam(b *testing.B) { 640 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 641 | benchRequest(b, githubMacaron, req) 642 | } 643 | func BenchmarkMartini_GithubParam(b *testing.B) { 644 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 645 | benchRequest(b, githubMartini, req) 646 | } 647 | func BenchmarkPat_GithubParam(b *testing.B) { 648 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 649 | benchRequest(b, githubPat, req) 650 | } 651 | func BenchmarkPossum_GithubParam(b *testing.B) { 652 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 653 | benchRequest(b, githubPossum, req) 654 | } 655 | func BenchmarkR2router_GithubParam(b *testing.B) { 656 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 657 | benchRequest(b, githubR2router, req) 658 | } 659 | 660 | // func BenchmarkRevel_GithubParam(b *testing.B) { 661 | // req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 662 | // benchRequest(b, githubRevel, req) 663 | // } 664 | func BenchmarkRivet_GithubParam(b *testing.B) { 665 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 666 | benchRequest(b, githubRivet, req) 667 | } 668 | func BenchmarkTango_GithubParam(b *testing.B) { 669 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 670 | benchRequest(b, githubTango, req) 671 | } 672 | func BenchmarkTigerTonic_GithubParam(b *testing.B) { 673 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 674 | benchRequest(b, githubTigerTonic, req) 675 | } 676 | func BenchmarkTraffic_GithubParam(b *testing.B) { 677 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 678 | benchRequest(b, githubTraffic, req) 679 | } 680 | func BenchmarkVulcan_GithubParam(b *testing.B) { 681 | req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 682 | benchRequest(b, githubVulcan, req) 683 | } 684 | 685 | // func BenchmarkZeus_GithubParam(b *testing.B) { 686 | // req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) 687 | // benchRequest(b, githubZeus, req) 688 | // } 689 | 690 | // All routes 691 | func BenchmarkAce_GithubAll(b *testing.B) { 692 | benchRoutes(b, githubAce, githubAPI) 693 | } 694 | func BenchmarkAero_GithubAll(b *testing.B) { 695 | benchRoutes(b, githubAero, githubAPI) 696 | } 697 | func BenchmarkBear_GithubAll(b *testing.B) { 698 | benchRoutes(b, githubBear, githubAPI) 699 | } 700 | func BenchmarkBeego_GithubAll(b *testing.B) { 701 | benchRoutes(b, githubBeego, githubAPI) 702 | } 703 | func BenchmarkBone_GithubAll(b *testing.B) { 704 | benchRoutes(b, githubBone, githubAPI) 705 | } 706 | func BenchmarkChi_GithubAll(b *testing.B) { 707 | benchRoutes(b, githubChi, githubAPI) 708 | } 709 | func BenchmarkCloudyKitRouter_GithubAll(b *testing.B) { 710 | benchRoutes(b, githubCloudyKitRouter, githubAPI) 711 | } 712 | func BenchmarkDenco_GithubAll(b *testing.B) { 713 | benchRoutes(b, githubDenco, githubAPI) 714 | } 715 | func BenchmarkEcho_GithubAll(b *testing.B) { 716 | benchRoutes(b, githubEcho, githubAPI) 717 | } 718 | func BenchmarkGin_GithubAll(b *testing.B) { 719 | benchRoutes(b, githubGin, githubAPI) 720 | } 721 | func BenchmarkGocraftWeb_GithubAll(b *testing.B) { 722 | benchRoutes(b, githubGocraftWeb, githubAPI) 723 | } 724 | func BenchmarkGoji_GithubAll(b *testing.B) { 725 | benchRoutes(b, githubGoji, githubAPI) 726 | } 727 | func BenchmarkGojiv2_GithubAll(b *testing.B) { 728 | benchRoutes(b, githubGojiv2, githubAPI) 729 | } 730 | func BenchmarkGoJsonRest_GithubAll(b *testing.B) { 731 | benchRoutes(b, githubGoJsonRest, githubAPI) 732 | } 733 | func BenchmarkGoRestful_GithubAll(b *testing.B) { 734 | benchRoutes(b, githubGoRestful, githubAPI) 735 | } 736 | func BenchmarkGorillaMux_GithubAll(b *testing.B) { 737 | benchRoutes(b, githubGorillaMux, githubAPI) 738 | } 739 | func BenchmarkGowwwRouter_GithubAll(b *testing.B) { 740 | benchRoutes(b, githubGowwwRouter, githubAPI) 741 | } 742 | func BenchmarkHttpRouter_GithubAll(b *testing.B) { 743 | benchRoutes(b, githubHttpRouter, githubAPI) 744 | } 745 | func BenchmarkHttpTreeMux_GithubAll(b *testing.B) { 746 | benchRoutes(b, githubHttpTreeMux, githubAPI) 747 | } 748 | func BenchmarkKocha_GithubAll(b *testing.B) { 749 | benchRoutes(b, githubKocha, githubAPI) 750 | } 751 | func BenchmarkLARS_GithubAll(b *testing.B) { 752 | benchRoutes(b, githubLARS, githubAPI) 753 | } 754 | func BenchmarkMacaron_GithubAll(b *testing.B) { 755 | benchRoutes(b, githubMacaron, githubAPI) 756 | } 757 | func BenchmarkMartini_GithubAll(b *testing.B) { 758 | benchRoutes(b, githubMartini, githubAPI) 759 | } 760 | func BenchmarkPat_GithubAll(b *testing.B) { 761 | benchRoutes(b, githubPat, githubAPI) 762 | } 763 | func BenchmarkPossum_GithubAll(b *testing.B) { 764 | benchRoutes(b, githubPossum, githubAPI) 765 | } 766 | func BenchmarkR2router_GithubAll(b *testing.B) { 767 | benchRoutes(b, githubR2router, githubAPI) 768 | } 769 | 770 | // func BenchmarkRevel_GithubAll(b *testing.B) { 771 | // benchRoutes(b, githubRevel, githubAPI) 772 | // } 773 | func BenchmarkRivet_GithubAll(b *testing.B) { 774 | benchRoutes(b, githubRivet, githubAPI) 775 | } 776 | func BenchmarkTango_GithubAll(b *testing.B) { 777 | benchRoutes(b, githubTango, githubAPI) 778 | } 779 | func BenchmarkTigerTonic_GithubAll(b *testing.B) { 780 | benchRoutes(b, githubTigerTonic, githubAPI) 781 | } 782 | func BenchmarkTraffic_GithubAll(b *testing.B) { 783 | benchRoutes(b, githubTraffic, githubAPI) 784 | } 785 | func BenchmarkVulcan_GithubAll(b *testing.B) { 786 | benchRoutes(b, githubVulcan, githubAPI) 787 | } 788 | 789 | // func BenchmarkZeus_GithubAll(b *testing.B) { 790 | // benchRoutes(b, githubZeus, githubAPI) 791 | // } 792 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/julienschmidt/go-http-routing-benchmark 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/aerogo/aero v1.3.42 7 | github.com/ant0ine/go-json-rest v3.3.2+incompatible 8 | github.com/astaxie/beego v1.12.0 9 | github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40 10 | github.com/cloudykit/router v0.0.0-20170501012743-15c4ed71df81 11 | github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect 12 | github.com/dimfeld/httptreemux v5.0.1+incompatible 13 | github.com/emicklei/go-restful v2.10.0+incompatible 14 | github.com/fsnotify/fsnotify v1.4.7 // indirect 15 | github.com/gin-gonic/gin v1.5.0 16 | github.com/go-chi/chi v4.0.2+incompatible 17 | github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab 18 | github.com/go-playground/form v3.1.4+incompatible // indirect 19 | github.com/go-playground/lars v4.0.1+incompatible 20 | github.com/go-zoo/bone v1.3.0 21 | github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b 22 | github.com/gorilla/mux v1.7.3 23 | github.com/gorilla/sessions v1.2.0 // indirect 24 | github.com/gorilla/websocket v1.4.1 // indirect 25 | github.com/gowww/router v0.0.0-20180327195201-5f9c626ef619 26 | github.com/gravitational/trace v0.0.0-20190726142706-a535a178675f // indirect 27 | github.com/jonboulle/clockwork v0.1.0 // indirect 28 | github.com/julienschmidt/httprouter v1.3.0 29 | github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect 30 | github.com/labstack/echo/v4 v4.1.11 31 | github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de 32 | github.com/lunny/tango v0.5.6 33 | github.com/mailgun/route v0.0.0-20181101151700-58b44163b968 34 | github.com/mikespook/possum v0.0.0-20170224044927-56d7ebb6470b 35 | github.com/naoina/denco v0.0.0-20180930074809-8475105a6b4c 36 | github.com/naoina/kocha-urlrouter v0.0.0-20140609163054-ad3a6f079210 37 | github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect 38 | github.com/philhofer/fwd v1.0.0 // indirect 39 | github.com/pilu/config v0.0.0-20131214182432-3eb99e6c0b9a // indirect 40 | github.com/pilu/miniassert v0.0.0-20140522125902-bee63581261a // indirect 41 | github.com/pilu/traffic v0.5.3 42 | github.com/plimble/ace v0.0.0-20180623113504-ba79f505f416 43 | github.com/plimble/sessions v0.0.0-20180326075456-7047d39da9ad // indirect 44 | github.com/plimble/utils v0.0.0-20150615054616-fe08d46675cd // indirect 45 | github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 // indirect 46 | github.com/rcrowley/go-tigertonic v0.0.0-20170420123839-fe6b9f080eb7 47 | github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b // indirect 48 | github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect 49 | github.com/sirupsen/logrus v1.4.2 // indirect 50 | github.com/tinylib/msgp v1.1.0 // indirect 51 | github.com/typepress/rivet v1.1.1-0.20151208095308-d62b4fcaf6b9 52 | github.com/unknwon/com v1.0.1 // indirect 53 | github.com/ursiform/bear v1.0.1 54 | github.com/vanng822/r2router v0.0.0-20150523112421-1023140a4f30 55 | github.com/vulcand/predicate v1.1.0 // indirect 56 | github.com/zenazn/goji v0.9.0 57 | goji.io v2.0.2+incompatible 58 | golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad // indirect 59 | golang.org/x/net v0.0.0-20190926025831-c00fd9afed17 // indirect 60 | gopkg.in/fsnotify.v1 v1.4.7 // indirect 61 | gopkg.in/ini.v1 v1.48.0 // indirect 62 | gopkg.in/macaron.v1 v1.3.4 63 | ) 64 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e h1:r1en/D7xJmcY24VkHkjkcJFa+7ZWubVWPBrvsHkmHxk= 2 | gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e/go.mod h1:uJEsN4LQpeGYRCjuPXPZBClU7N5pWzGuyF4uqLpE/e0= 3 | github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= 4 | github.com/OwnLocal/goes v1.0.0/go.mod h1:8rIFjBGTue3lCU0wplczcUgt9Gxgrkkrw7etMIcn8TM= 5 | github.com/aerogo/aero v1.3.42 h1:MW/zMYnlyzATokbSUHTq8aGGja3SCA9eUuKj+ueoRyA= 6 | github.com/aerogo/aero v1.3.42/go.mod h1:txzRPPK6C3KsmGmSuoDm42K6R6vDVNLd/uO0g7d1T7U= 7 | github.com/aerogo/csp v0.1.10 h1:2PJf9gkdRvCFYOA0baTUyp34vwPp5ZJJX8GZRCYc/nM= 8 | github.com/aerogo/csp v0.1.10/go.mod h1:UrxbTXv+X9kJatyuLeu2yGFpOiWVPjbqA/DzqxSVhl8= 9 | github.com/aerogo/http v1.0.12/go.mod h1:nUN1X1Kyh7tj5hi0ufaqLhENHA0iF3nCoGZDSGabEog= 10 | github.com/aerogo/http v1.1.1 h1:b7/19Did2TKmpeSWgByN1GBG2KnXlj4v6nZdKX6+yEE= 11 | github.com/aerogo/http v1.1.1/go.mod h1:5VMFMcmM5djh6c7L/v++HUjFvVz+7ER2t2NfXRrzohk= 12 | github.com/aerogo/linter-performance v1.0.6 h1:BrMKf+4s4hlKf7tV+B9/YQzTz7LKWmWZckPhyAn/+MY= 13 | github.com/aerogo/linter-performance v1.0.6/go.mod h1:E5myVvu3+U1NmdW3c+A6xs9Me/U/Ey4Khz35uJdB5Yc= 14 | github.com/aerogo/session v0.1.8 h1:l28Ii/YBfh4/vDWOc1YXLXg2vkHsRFuMLAeVhhl1eME= 15 | github.com/aerogo/session v0.1.8/go.mod h1:Q9QqpT8nM6HTaklE14T+bzNSKrwW1M2wZ/NZV1HUTB0= 16 | github.com/aerogo/session-store-memory v0.1.9 h1:1OswTCtyqzffX5aGr6jI3H8gt/hkU3LKNiKpia7ntcs= 17 | github.com/aerogo/session-store-memory v0.1.9/go.mod h1:z4ZxP+xLVdH69F/Cvgy93v8fWzeDmiJo+Mm+Th3un4c= 18 | github.com/akyoto/assert v0.2.2/go.mod h1:g5e6ag+ksCEQENq/LnmU9z04wCAIFDr8KacBusVL0H8= 19 | github.com/akyoto/assert v0.2.3/go.mod h1:g5e6ag+ksCEQENq/LnmU9z04wCAIFDr8KacBusVL0H8= 20 | github.com/akyoto/assert v0.2.4 h1:n0FwcNH5dMYq3I8Iu7MOR1WWGkkGH8ao84nvCRJmsbs= 21 | github.com/akyoto/assert v0.2.4/go.mod h1:SoqVayyOmM/YSBnwOxJHCt4BCocoIrgeceWtJV701C0= 22 | github.com/akyoto/color v1.8.11 h1:uCQi+uRyngo1cJhJSv28PQmduGFiOAGNF6F9MFoRDek= 23 | github.com/akyoto/color v1.8.11/go.mod h1:Q77HnNKrgGSfXOpkR7cuyazaOXQsKLWKbDPh2cy+jto= 24 | github.com/akyoto/colorable v0.1.7 h1:ge91E25hiOiT/Zu47ij/rTO3cks7wMlTrcQspua1hFM= 25 | github.com/akyoto/colorable v0.1.7/go.mod h1:zlc1+Es4DyoXzDdbKiSfvdM6R/DsWS8bFi4RHigkuu4= 26 | github.com/akyoto/hash v0.4.8 h1:4PdsvyWLon+nMHsP4tZEZb7MiNFil16XqdwyWpY+uaQ= 27 | github.com/akyoto/hash v0.4.8/go.mod h1:ukwV/qacn7OahWH01ogEYvmS4Y0y5yZpauSRhWTdmR8= 28 | github.com/akyoto/stringutils v0.2.6/go.mod h1:OPVSI2QOvOGJ8GZoVdsS5BrAUb/l9zf63QgMvLPYOjQ= 29 | github.com/akyoto/stringutils v0.3.0 h1:NJpcnpvp1dYmJAvuZapj1D5aEDRPv+c8vAva7qSklL4= 30 | github.com/akyoto/stringutils v0.3.0/go.mod h1:v+Lr6tJxVd/Q1InaxsqaSXO+vSkG7MYMNc9Y9ul6Mkc= 31 | github.com/akyoto/tty v0.1.3 h1:AdnLETzgooimWLvoBQLn5bT1j+i0yiB4E596BfFKnmA= 32 | github.com/akyoto/tty v0.1.3/go.mod h1:+VlbvviCaiwhS4oGpO+iBtC0lYG1ilIs3ZhUnT1Ppgo= 33 | github.com/akyoto/uuid v1.1.3 h1:FEz14tNTfaUeY0Jrkz2F17rjKiks6hOALGcPmAmtn1s= 34 | github.com/akyoto/uuid v1.1.3/go.mod h1:8dgzDQyrpuApBGIQHOX7JkvCZHusXZ0tGlQcxxv4bYg= 35 | github.com/ant0ine/go-json-rest v3.3.2+incompatible h1:nBixrkLFiDNAW0hauKDLc8yJI6XfrQumWvytE1Hk14E= 36 | github.com/ant0ine/go-json-rest v3.3.2+incompatible/go.mod h1:q6aCt0GfU6LhpBsnZ/2U+mwe+0XB5WStbmwyoPfc+sk= 37 | github.com/astaxie/beego v1.12.0 h1:MRhVoeeye5N+Flul5PoVfD9CslfdoH+xqC/xvSQ5u2Y= 38 | github.com/astaxie/beego v1.12.0/go.mod h1:fysx+LZNZKnvh4GED/xND7jWtjCR6HzydR2Hh2Im57o= 39 | github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ= 40 | github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU= 41 | github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40 h1:y4B3+GPxKlrigF1ha5FFErxK+sr6sWxQovRMzwMhejo= 42 | github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= 43 | github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= 44 | github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE= 45 | github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= 46 | github.com/cloudykit/router v0.0.0-20170501012743-15c4ed71df81 h1:aJJ1Q5RKhZo824sL70umU/tBvCYadbcqq6T9O8jPlck= 47 | github.com/cloudykit/router v0.0.0-20170501012743-15c4ed71df81/go.mod h1:12CrAbzvpmFeVKCqPqA9wVmO4T6TdFhCq3Nc+z8Sl/Q= 48 | github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= 49 | github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= 50 | github.com/couchbase/go-couchbase v0.0.0-20181122212707-3e9b6e1258bb/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U= 51 | github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c= 52 | github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= 53 | github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY= 54 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 55 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 56 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 57 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= 58 | github.com/dimfeld/httptreemux v5.0.1+incompatible h1:Qj3gVcDNoOthBAqftuD596rm4wg/adLLz5xh5CmpiCA= 59 | github.com/dimfeld/httptreemux v5.0.1+incompatible/go.mod h1:rbUlSV+CCpv/SuqUTP/8Bk2O3LyUV436/yaRGkhP6Z0= 60 | github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= 61 | github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk= 62 | github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= 63 | github.com/emicklei/go-restful v2.10.0+incompatible h1:l6Soi8WCOOVAeCo4W98iBFC6Og7/X8bpRt51oNLZ2C8= 64 | github.com/emicklei/go-restful v2.10.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= 65 | github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= 66 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 67 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 68 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 69 | github.com/gin-gonic/gin v1.5.0 h1:fi+bqFAx/oLK54somfCtEZs9HeH1LHVoEPUgARpTqyc= 70 | github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= 71 | github.com/go-chi/chi v4.0.2+incompatible h1:maB6vn6FqCxrpz4FqWdh4+lwpyZIQS7YEAUcHlgXVRs= 72 | github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= 73 | github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191 h1:NjHlg70DuOkcAMqgt0+XA+NHwtu66MkTVVgR4fFWbcI= 74 | github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191/go.mod h1:VFI2o2q9kYsC4o7VP1HrEVosiZZTd+MVT3YZx4gqvJw= 75 | github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk= 76 | github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= 77 | github.com/go-playground/form v3.1.4+incompatible h1:lvKiHVxE2WvzDIoyMnWcjyiBxKt2+uFJyZcPYWsLnjI= 78 | github.com/go-playground/form v3.1.4+incompatible/go.mod h1:lhcKXfTuhRtIZCIKUeJ0b5F207aeQCPbZU09ScKjwWg= 79 | github.com/go-playground/lars v4.0.1+incompatible h1:d0q8YUzAggHd1iiWgIJKLpHMa2VLEc5a/oCIJLxjHgY= 80 | github.com/go-playground/lars v4.0.1+incompatible/go.mod h1:N3/k870eeSGPNoqbBzTb/PUpQ3uI5ag39Gt8TquOoEo= 81 | github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc= 82 | github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= 83 | github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM= 84 | github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= 85 | github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= 86 | github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 87 | github.com/go-zoo/bone v1.3.0 h1:PY6sHq37FnQhj+4ZyqFIzJQHvrrGx0GEc3vTZZC/OsI= 88 | github.com/go-zoo/bone v1.3.0/go.mod h1:HI3Lhb7G3UQcAwEhOJ2WyNcsFtQX1WYHa0Hl4OBbhW8= 89 | github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b h1:g2Qcs0B+vOQE1L3a7WQ/JUUSzJnHbTz14qkJSqEWcF4= 90 | github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b/go.mod h1:Ag7UMbZNGrnHwaXPJOUKJIVgx4QOWMOWZngrvsN6qak= 91 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 92 | github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= 93 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 94 | github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 95 | github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= 96 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 97 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 98 | github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 99 | github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= 100 | github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 101 | github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= 102 | github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= 103 | github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= 104 | github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= 105 | github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ= 106 | github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= 107 | github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= 108 | github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 109 | github.com/gowww/router v0.0.0-20180327195201-5f9c626ef619 h1:nS1DFy3mh1wK3zm1xGtvMnWje5zA9zVJTLuPKBovHVw= 110 | github.com/gowww/router v0.0.0-20180327195201-5f9c626ef619/go.mod h1:avUfKJbpfLNee1EI8ur7ckKAuIuT7hHNZhGrBsRKnNY= 111 | github.com/gravitational/trace v0.0.0-20190726142706-a535a178675f h1:68WxnfBzJRYktZ30fmIjGQ74RsXYLoeH2/NITPktTMY= 112 | github.com/gravitational/trace v0.0.0-20190726142706-a535a178675f/go.mod h1:RvdOUHE4SHqR3oXlFFKnGzms8a5dugHygGw1bqDstYI= 113 | github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= 114 | github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= 115 | github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= 116 | github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 117 | github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 118 | github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= 119 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 120 | github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= 121 | github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= 122 | github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= 123 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 124 | github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= 125 | github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 126 | github.com/labstack/echo/v4 v4.1.11 h1:z0BZoArY4FqdpUEl+wlHp4hnr/oSR6MTmQmv8OHSoww= 127 | github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= 128 | github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0= 129 | github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= 130 | github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8= 131 | github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= 132 | github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 133 | github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de h1:nyxwRdWHAVxpFcDThedEgQ07DbcRc5xgNObtbTp76fk= 134 | github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ= 135 | github.com/lunny/tango v0.5.6 h1:QeUe+2ksZ3LScC+SKhDbS1wbS/ctuyRnZ3fAsL10J4M= 136 | github.com/lunny/tango v0.5.6/go.mod h1:qW1SakbmM67DdOHN6mipeYWhB1Uu6lYsgU3u6fQmu5o= 137 | github.com/mailgun/route v0.0.0-20181101151700-58b44163b968 h1:8usGWS9lr8nrFEf4j3mUfZGpXHV2ng3Rmlknh4tp5NE= 138 | github.com/mailgun/route v0.0.0-20181101151700-58b44163b968/go.mod h1:iitUOLTydv/b+q12z6vQ163uUDAZmUa5O2i/fOo7P7M= 139 | github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= 140 | github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 141 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 142 | github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg= 143 | github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= 144 | github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= 145 | github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 146 | github.com/mikespook/possum v0.0.0-20170224044927-56d7ebb6470b h1:UpTyMObxdqOJ+QjsW+FBt/grs0MceNRDFVbPH9vx9kI= 147 | github.com/mikespook/possum v0.0.0-20170224044927-56d7ebb6470b/go.mod h1:hNxCw7x0yDbIykxTaAba/7mQm8tgQq5m8i6nxV45ng4= 148 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 149 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 150 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= 151 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 152 | github.com/naoina/denco v0.0.0-20180930074809-8475105a6b4c h1:OuYPoLEOYbguEn/ihiCTfWM0cjzY5R77CA2vzmx2M8Y= 153 | github.com/naoina/denco v0.0.0-20180930074809-8475105a6b4c/go.mod h1:rJwHqj5scxcViM0kq4dh/d1E9sLBeI1snvkNVX4mQGY= 154 | github.com/naoina/kocha-urlrouter v0.0.0-20140609163054-ad3a6f079210 h1:3U8/mV2GqWsaM9XZZL+sbmF3mDM0rmWZBw8iI/F6Qqg= 155 | github.com/naoina/kocha-urlrouter v0.0.0-20140609163054-ad3a6f079210/go.mod h1:32uT1OraQUMXWWvMR/uLjbcnSPmR38HsVEhlInnJ1CU= 156 | github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw= 157 | github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0= 158 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 159 | github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ= 160 | github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= 161 | github.com/pilu/config v0.0.0-20131214182432-3eb99e6c0b9a h1:Tg4E4cXPZSZyd3H1tJlYo6ZreXV0ZJvE/lorNqyw1AU= 162 | github.com/pilu/config v0.0.0-20131214182432-3eb99e6c0b9a/go.mod h1:9Or9aIl95Kp43zONcHd5tLZGKXb9iLx0pZjau0uJ5zg= 163 | github.com/pilu/miniassert v0.0.0-20140522125902-bee63581261a h1:U8Xgy85P2npR1jqpNF4q9rLSt6kzrOrWubkepc3lWbE= 164 | github.com/pilu/miniassert v0.0.0-20140522125902-bee63581261a/go.mod h1:QKd9TvGj31l6g+MV2PqthhK68d5ZPv/Q2PvtsS0mM3I= 165 | github.com/pilu/traffic v0.5.3 h1:gzDC+/uF1JQNnpcjUhVnw3z9xTBKx9y9FLtdLkHrIbQ= 166 | github.com/pilu/traffic v0.5.3/go.mod h1:pPbakW2fofyQaXrh319Xb9TJpM8gjs/vp+71CztjeK0= 167 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 168 | github.com/plimble/ace v0.0.0-20180623113504-ba79f505f416 h1:44dXuMsR/fri/mpAkHv0+qEpeXwOOhU/hqAgmZnU6P4= 169 | github.com/plimble/ace v0.0.0-20180623113504-ba79f505f416/go.mod h1:2xqEu03zJ11kRazFk9k72JtfU2Nb6Gb2GZQEzyq4ZzI= 170 | github.com/plimble/sessions v0.0.0-20180326075456-7047d39da9ad h1:k+Mp1U6g3HzuTXiAEU2CGW675jibZ+v663SewgXJjW0= 171 | github.com/plimble/sessions v0.0.0-20180326075456-7047d39da9ad/go.mod h1:SOvlms0FUIL/aE3RsFFtPnkOwGa0yWKSlZdbuHq4lf4= 172 | github.com/plimble/utils v0.0.0-20150615054616-fe08d46675cd h1:a/OxgUvo03VLeAIOTwG92bB6HBsZcf1epwvLfp5uCoU= 173 | github.com/plimble/utils v0.0.0-20150615054616-fe08d46675cd/go.mod h1:hdBKa62O0OK5mae6xnibGMZRr86u5TM6thzlgxtbEG8= 174 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 175 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 176 | github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 h1:dY6ETXrvDG7Sa4vE8ZQG4yqWg6UnOcbqTAahkV813vQ= 177 | github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= 178 | github.com/rcrowley/go-tigertonic v0.0.0-20170420123839-fe6b9f080eb7 h1:IF6au04LnXfITvXy4gwKKcka4zKYp73RXCEGUACqC/Y= 179 | github.com/rcrowley/go-tigertonic v0.0.0-20170420123839-fe6b9f080eb7/go.mod h1:iFmRpXEuybfivhzfxebaHxO63V+ye2AFJMBk12tZPck= 180 | github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybLANtM3mBXNUtOfsCFXeTsnBqCsx1KM= 181 | github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= 182 | github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI+b2qND5gpH8YhURn0k8OCaeRnkINo= 183 | github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg= 184 | github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= 185 | github.com/siddontang/ledisdb v0.0.0-20181029004158-becf5f38d373/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg= 186 | github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA= 187 | github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= 188 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 189 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= 190 | github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= 191 | github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= 192 | github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= 193 | github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= 194 | github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= 195 | github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 196 | github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE= 197 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 198 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 199 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 200 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 201 | github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= 202 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 203 | github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= 204 | github.com/tinylib/msgp v1.1.0 h1:9fQd+ICuRIu/ue4vxJZu6/LzxN0HwMds2nq/0cFvxHU= 205 | github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= 206 | github.com/typepress/rivet v1.1.1-0.20151208095308-d62b4fcaf6b9 h1:0K3sMkRlwGiFT5cz+lkkoLHAS7ZjaWIqVfeJULc60hA= 207 | github.com/typepress/rivet v1.1.1-0.20151208095308-d62b4fcaf6b9/go.mod h1:HRZQrhGecIqMtvm7AlZh7Bur48EOThdZuQcI3ePUa5M= 208 | github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= 209 | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= 210 | github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= 211 | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 212 | github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM= 213 | github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= 214 | github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs= 215 | github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= 216 | github.com/ursiform/bear v1.0.1 h1:77/y+Hiir4LyLTyUdj0MmxpcW6rYLgeX8WLLxM7e7uY= 217 | github.com/ursiform/bear v1.0.1/go.mod h1:AYsqyNUafOkYwqZV0zZeBkTOpfCRfWCNWvO5CnO7Tv4= 218 | github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= 219 | github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 220 | github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= 221 | github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= 222 | github.com/vanng822/r2router v0.0.0-20150523112421-1023140a4f30 h1:fCYIzI798sOjtO9fMZaqF0ldAoYEsMLt2EwX7HdXzu4= 223 | github.com/vanng822/r2router v0.0.0-20150523112421-1023140a4f30/go.mod h1:1BVq8p2jVr55Ost2PkZWDrG86PiJ/0lxqcXoAcGxvWU= 224 | github.com/vulcand/predicate v1.1.0 h1:Gq/uWopa4rx/tnZu2opOSBqHK63Yqlou/SzrbwdJiNg= 225 | github.com/vulcand/predicate v1.1.0/go.mod h1:mlccC5IRBoc2cIFmCB8ZM62I3VDb6p2GXESMHa3CnZg= 226 | github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc= 227 | github.com/zeebo/xxh3 v0.0.0-20191021174148-b56a7dc3d80c h1:3PaZXPP1fMCBSQzwmcfLs0pX9wOeZpKduDDcvp6lKCc= 228 | github.com/zeebo/xxh3 v0.0.0-20191021174148-b56a7dc3d80c/go.mod h1:e/zZObEJWtkq6f+bAzme0xQJSGI75oxoeqS+f2I7YVI= 229 | github.com/zenazn/goji v0.9.0 h1:RSQQAbXGArQ0dIDEq+PI6WqN6if+5KHu6x2Cx/GXLTQ= 230 | github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= 231 | goji.io v2.0.2+incompatible h1:uIssv/elbKRLznFUy3Xj4+2Mz/qKhek/9aZQDUMae7c= 232 | goji.io v2.0.2+incompatible/go.mod h1:sbqFwrtqZACxLBTQcdgVjFh54yGVCvwq8+w49MVMMIk= 233 | golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 234 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 235 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= 236 | golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 237 | golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad h1:5E5raQxcv+6CZ11RrBYQe5WRbUIWpScjh0kvHZkZIrQ= 238 | golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 239 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 240 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 241 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 242 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 243 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= 244 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 245 | golang.org/x/net v0.0.0-20190926025831-c00fd9afed17 h1:qPnAdmjNA41t3QBTx2mFGf/SD1IoslhYu7AmdsVzCcs= 246 | golang.org/x/net v0.0.0-20190926025831-c00fd9afed17/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 247 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 248 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 249 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 250 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 251 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 252 | golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 253 | golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= 254 | golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 255 | golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 256 | golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339 h1:zSqWKgm/o7HAnlAzBQ+aetp9fpuyytsXnKA8eiLHYQM= 257 | golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 258 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 259 | golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= 260 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 261 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 262 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 263 | golang.org/x/tools v0.0.0-20190802220118-1d1727260058/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= 264 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 265 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 266 | gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= 267 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 268 | gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= 269 | gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= 270 | gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc= 271 | gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= 272 | gopkg.in/ini.v1 v1.46.0 h1:VeDZbLYGaupuvIrsYCEOe/L/2Pcs5n7hdO1ZTjporag= 273 | gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 274 | gopkg.in/ini.v1 v1.48.0 h1:URjZc+8ugRY5mL5uUeQH/a63JcHwdX9xZaWvmNWD7z8= 275 | gopkg.in/ini.v1 v1.48.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 276 | gopkg.in/macaron.v1 v1.3.4 h1:HvIscOwxhFhx3swWM/979wh2QMYyuXrNmrF9l+j3HZs= 277 | gopkg.in/macaron.v1 v1.3.4/go.mod h1:/RoHTdC8ALpyJ3+QR36mKjwnT1F1dyYtsGM9Ate6ZFI= 278 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 279 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= 280 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 281 | -------------------------------------------------------------------------------- /gplus_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Julien Schmidt. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be found 3 | // in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "net/http" 9 | "testing" 10 | ) 11 | 12 | // Google+ 13 | // https://developers.google.com/+/api/latest/ 14 | // (in reality this is just a subset of a much larger API) 15 | var gplusAPI = []route{ 16 | // People 17 | {"GET", "/people/:userId"}, 18 | {"GET", "/people"}, 19 | {"GET", "/activities/:activityId/people/:collection"}, 20 | {"GET", "/people/:userId/people/:collection"}, 21 | {"GET", "/people/:userId/openIdConnect"}, 22 | 23 | // Activities 24 | {"GET", "/people/:userId/activities/:collection"}, 25 | {"GET", "/activities/:activityId"}, 26 | {"GET", "/activities"}, 27 | 28 | // Comments 29 | {"GET", "/activities/:activityId/comments"}, 30 | {"GET", "/comments/:commentId"}, 31 | 32 | // Moments 33 | {"POST", "/people/:userId/moments/:collection"}, 34 | {"GET", "/people/:userId/moments/:collection"}, 35 | {"DELETE", "/moments/:id"}, 36 | } 37 | 38 | var ( 39 | gplusAce http.Handler 40 | gplusAero http.Handler 41 | gplusBear http.Handler 42 | gplusBeego http.Handler 43 | gplusBone http.Handler 44 | gplusChi http.Handler 45 | gplusCloudyKitRouter http.Handler 46 | gplusDenco http.Handler 47 | gplusEcho http.Handler 48 | gplusGin http.Handler 49 | gplusGocraftWeb http.Handler 50 | gplusGoji http.Handler 51 | gplusGojiv2 http.Handler 52 | gplusGoJsonRest http.Handler 53 | gplusGoRestful http.Handler 54 | gplusGorillaMux http.Handler 55 | gplusGowwwRouter http.Handler 56 | gplusHttpRouter http.Handler 57 | gplusHttpTreeMux http.Handler 58 | gplusKocha http.Handler 59 | gplusLARS http.Handler 60 | gplusMacaron http.Handler 61 | gplusMartini http.Handler 62 | gplusPat http.Handler 63 | gplusPossum http.Handler 64 | gplusR2router http.Handler 65 | gplusRevel http.Handler 66 | gplusRivet http.Handler 67 | gplusTango http.Handler 68 | gplusTigerTonic http.Handler 69 | gplusTraffic http.Handler 70 | gplusVulcan http.Handler 71 | // gplusZeus http.Handler 72 | ) 73 | 74 | func init() { 75 | println("#GPlusAPI Routes:", len(gplusAPI)) 76 | 77 | calcMem("Ace", func() { 78 | gplusAce = loadAce(gplusAPI) 79 | }) 80 | calcMem("Aero", func() { 81 | gplusAero = loadAero(gplusAPI) 82 | }) 83 | calcMem("Bear", func() { 84 | gplusBear = loadBear(gplusAPI) 85 | }) 86 | calcMem("Beego", func() { 87 | gplusBeego = loadBeego(gplusAPI) 88 | }) 89 | calcMem("Bone", func() { 90 | gplusBone = loadBone(gplusAPI) 91 | }) 92 | calcMem("Chi", func() { 93 | gplusChi = loadChi(gplusAPI) 94 | }) 95 | calcMem("CloudyKitRouter", func() { 96 | gplusCloudyKitRouter = loadCloudyKitRouter(gplusAPI) 97 | }) 98 | calcMem("Denco", func() { 99 | gplusDenco = loadDenco(gplusAPI) 100 | }) 101 | calcMem("Echo", func() { 102 | gplusEcho = loadEcho(gplusAPI) 103 | }) 104 | calcMem("Gin", func() { 105 | gplusGin = loadGin(gplusAPI) 106 | }) 107 | calcMem("GocraftWeb", func() { 108 | gplusGocraftWeb = loadGocraftWeb(gplusAPI) 109 | }) 110 | calcMem("Goji", func() { 111 | gplusGoji = loadGoji(gplusAPI) 112 | }) 113 | calcMem("Gojiv2", func() { 114 | gplusGojiv2 = loadGojiv2(gplusAPI) 115 | }) 116 | calcMem("GoJsonRest", func() { 117 | gplusGoJsonRest = loadGoJsonRest(gplusAPI) 118 | }) 119 | calcMem("GoRestful", func() { 120 | gplusGoRestful = loadGoRestful(gplusAPI) 121 | }) 122 | calcMem("GorillaMux", func() { 123 | gplusGorillaMux = loadGorillaMux(gplusAPI) 124 | }) 125 | calcMem("GowwwRouter", func() { 126 | gplusGowwwRouter = loadGowwwRouter(gplusAPI) 127 | }) 128 | calcMem("HttpRouter", func() { 129 | gplusHttpRouter = loadHttpRouter(gplusAPI) 130 | }) 131 | calcMem("HttpTreeMux", func() { 132 | gplusHttpTreeMux = loadHttpTreeMux(gplusAPI) 133 | }) 134 | calcMem("Kocha", func() { 135 | gplusKocha = loadKocha(gplusAPI) 136 | }) 137 | calcMem("LARS", func() { 138 | gplusLARS = loadLARS(gplusAPI) 139 | }) 140 | calcMem("Macaron", func() { 141 | gplusMacaron = loadMacaron(gplusAPI) 142 | }) 143 | calcMem("Martini", func() { 144 | gplusMartini = loadMartini(gplusAPI) 145 | }) 146 | calcMem("Pat", func() { 147 | gplusPat = loadPat(gplusAPI) 148 | }) 149 | calcMem("Possum", func() { 150 | gplusPossum = loadPossum(gplusAPI) 151 | }) 152 | calcMem("R2router", func() { 153 | gplusR2router = loadR2router(gplusAPI) 154 | }) 155 | // calcMem("Revel", func() { 156 | // gplusRevel = loadRevel(gplusAPI) 157 | // }) 158 | calcMem("Rivet", func() { 159 | gplusRivet = loadRivet(gplusAPI) 160 | }) 161 | calcMem("Tango", func() { 162 | gplusTango = loadTango(gplusAPI) 163 | }) 164 | calcMem("TigerTonic", func() { 165 | gplusTigerTonic = loadTigerTonic(gplusAPI) 166 | }) 167 | calcMem("Traffic", func() { 168 | gplusTraffic = loadTraffic(gplusAPI) 169 | }) 170 | calcMem("Vulcan", func() { 171 | gplusVulcan = loadVulcan(gplusAPI) 172 | }) 173 | // calcMem("Zeus", func() { 174 | // gplusZeus = loadZeus(gplusAPI) 175 | // }) 176 | 177 | println() 178 | } 179 | 180 | // Static 181 | func BenchmarkAce_GPlusStatic(b *testing.B) { 182 | req, _ := http.NewRequest("GET", "/people", nil) 183 | benchRequest(b, gplusAce, req) 184 | } 185 | func BenchmarkAero_GPlusStatic(b *testing.B) { 186 | req, _ := http.NewRequest("GET", "/people", nil) 187 | benchRequest(b, gplusAero, req) 188 | } 189 | func BenchmarkBear_GPlusStatic(b *testing.B) { 190 | req, _ := http.NewRequest("GET", "/people", nil) 191 | benchRequest(b, gplusBear, req) 192 | } 193 | func BenchmarkBeego_GPlusStatic(b *testing.B) { 194 | req, _ := http.NewRequest("GET", "/people", nil) 195 | benchRequest(b, gplusBeego, req) 196 | } 197 | func BenchmarkBone_GPlusStatic(b *testing.B) { 198 | req, _ := http.NewRequest("GET", "/people", nil) 199 | benchRequest(b, gplusBone, req) 200 | } 201 | func BenchmarkChi_GPlusStatic(b *testing.B) { 202 | req, _ := http.NewRequest("GET", "/people", nil) 203 | benchRequest(b, gplusChi, req) 204 | } 205 | func BenchmarkCloudyKitRouter_GPlusStatic(b *testing.B) { 206 | req, _ := http.NewRequest("GET", "/people", nil) 207 | benchRequest(b, gplusCloudyKitRouter, req) 208 | } 209 | func BenchmarkDenco_GPlusStatic(b *testing.B) { 210 | req, _ := http.NewRequest("GET", "/people", nil) 211 | benchRequest(b, gplusDenco, req) 212 | } 213 | func BenchmarkEcho_GPlusStatic(b *testing.B) { 214 | req, _ := http.NewRequest("GET", "/people", nil) 215 | benchRequest(b, gplusEcho, req) 216 | } 217 | func BenchmarkGin_GPlusStatic(b *testing.B) { 218 | req, _ := http.NewRequest("GET", "/people", nil) 219 | benchRequest(b, gplusGin, req) 220 | } 221 | func BenchmarkGocraftWeb_GPlusStatic(b *testing.B) { 222 | req, _ := http.NewRequest("GET", "/people", nil) 223 | benchRequest(b, gplusGocraftWeb, req) 224 | } 225 | func BenchmarkGoji_GPlusStatic(b *testing.B) { 226 | req, _ := http.NewRequest("GET", "/people", nil) 227 | benchRequest(b, gplusGoji, req) 228 | } 229 | func BenchmarkGojiv2_GPlusStatic(b *testing.B) { 230 | req, _ := http.NewRequest("GET", "/people", nil) 231 | benchRequest(b, gplusGojiv2, req) 232 | } 233 | func BenchmarkGoJsonRest_GPlusStatic(b *testing.B) { 234 | req, _ := http.NewRequest("GET", "/people", nil) 235 | benchRequest(b, gplusGoJsonRest, req) 236 | } 237 | func BenchmarkGoRestful_GPlusStatic(b *testing.B) { 238 | req, _ := http.NewRequest("GET", "/people", nil) 239 | benchRequest(b, gplusGoRestful, req) 240 | } 241 | func BenchmarkGorillaMux_GPlusStatic(b *testing.B) { 242 | req, _ := http.NewRequest("GET", "/people", nil) 243 | benchRequest(b, gplusGorillaMux, req) 244 | } 245 | func BenchmarkGowwwRouter_GPlusStatic(b *testing.B) { 246 | req, _ := http.NewRequest("GET", "/people", nil) 247 | benchRequest(b, gplusGowwwRouter, req) 248 | } 249 | func BenchmarkHttpRouter_GPlusStatic(b *testing.B) { 250 | req, _ := http.NewRequest("GET", "/people", nil) 251 | benchRequest(b, gplusHttpRouter, req) 252 | } 253 | func BenchmarkHttpTreeMux_GPlusStatic(b *testing.B) { 254 | req, _ := http.NewRequest("GET", "/people", nil) 255 | benchRequest(b, gplusHttpTreeMux, req) 256 | } 257 | func BenchmarkKocha_GPlusStatic(b *testing.B) { 258 | req, _ := http.NewRequest("GET", "/people", nil) 259 | benchRequest(b, gplusKocha, req) 260 | } 261 | func BenchmarkLARS_GPlusStatic(b *testing.B) { 262 | req, _ := http.NewRequest("GET", "/people", nil) 263 | benchRequest(b, gplusLARS, req) 264 | } 265 | func BenchmarkMacaron_GPlusStatic(b *testing.B) { 266 | req, _ := http.NewRequest("GET", "/people", nil) 267 | benchRequest(b, gplusMacaron, req) 268 | } 269 | func BenchmarkMartini_GPlusStatic(b *testing.B) { 270 | req, _ := http.NewRequest("GET", "/people", nil) 271 | benchRequest(b, gplusMartini, req) 272 | } 273 | func BenchmarkPat_GPlusStatic(b *testing.B) { 274 | req, _ := http.NewRequest("GET", "/people", nil) 275 | benchRequest(b, gplusPat, req) 276 | } 277 | func BenchmarkPossum_GPlusStatic(b *testing.B) { 278 | req, _ := http.NewRequest("GET", "/people", nil) 279 | benchRequest(b, gplusPossum, req) 280 | } 281 | func BenchmarkR2router_GPlusStatic(b *testing.B) { 282 | req, _ := http.NewRequest("GET", "/people", nil) 283 | benchRequest(b, gplusR2router, req) 284 | } 285 | 286 | // func BenchmarkRevel_GPlusStatic(b *testing.B) { 287 | // req, _ := http.NewRequest("GET", "/people", nil) 288 | // benchRequest(b, gplusRevel, req) 289 | // } 290 | func BenchmarkRivet_GPlusStatic(b *testing.B) { 291 | req, _ := http.NewRequest("GET", "/people", nil) 292 | benchRequest(b, gplusRivet, req) 293 | } 294 | func BenchmarkTango_GPlusStatic(b *testing.B) { 295 | req, _ := http.NewRequest("GET", "/people", nil) 296 | benchRequest(b, gplusTango, req) 297 | } 298 | func BenchmarkTigerTonic_GPlusStatic(b *testing.B) { 299 | req, _ := http.NewRequest("GET", "/people", nil) 300 | benchRequest(b, gplusTigerTonic, req) 301 | } 302 | func BenchmarkTraffic_GPlusStatic(b *testing.B) { 303 | req, _ := http.NewRequest("GET", "/people", nil) 304 | benchRequest(b, gplusTraffic, req) 305 | } 306 | func BenchmarkVulcan_GPlusStatic(b *testing.B) { 307 | req, _ := http.NewRequest("GET", "/people", nil) 308 | benchRequest(b, gplusVulcan, req) 309 | } 310 | 311 | // func BenchmarkZeus_GPlusStatic(b *testing.B) { 312 | // req, _ := http.NewRequest("GET", "/people", nil) 313 | // benchRequest(b, gplusZeus, req) 314 | // } 315 | 316 | // One Param 317 | func BenchmarkAce_GPlusParam(b *testing.B) { 318 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 319 | benchRequest(b, gplusAce, req) 320 | } 321 | func BenchmarkAero_GPlusParam(b *testing.B) { 322 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 323 | benchRequest(b, gplusAero, req) 324 | } 325 | func BenchmarkBear_GPlusParam(b *testing.B) { 326 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 327 | benchRequest(b, gplusBear, req) 328 | } 329 | func BenchmarkBeego_GPlusParam(b *testing.B) { 330 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 331 | benchRequest(b, gplusBeego, req) 332 | } 333 | func BenchmarkBone_GPlusParam(b *testing.B) { 334 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 335 | benchRequest(b, gplusBone, req) 336 | } 337 | func BenchmarkChi_GPlusParam(b *testing.B) { 338 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 339 | benchRequest(b, gplusChi, req) 340 | } 341 | func BenchmarkCloudyKitRouter_GPlusParam(b *testing.B) { 342 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 343 | benchRequest(b, gplusCloudyKitRouter, req) 344 | } 345 | func BenchmarkDenco_GPlusParam(b *testing.B) { 346 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 347 | benchRequest(b, gplusDenco, req) 348 | } 349 | func BenchmarkEcho_GPlusParam(b *testing.B) { 350 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 351 | benchRequest(b, gplusEcho, req) 352 | } 353 | func BenchmarkGin_GPlusParam(b *testing.B) { 354 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 355 | benchRequest(b, gplusGin, req) 356 | } 357 | func BenchmarkGocraftWeb_GPlusParam(b *testing.B) { 358 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 359 | benchRequest(b, gplusGocraftWeb, req) 360 | } 361 | func BenchmarkGoji_GPlusParam(b *testing.B) { 362 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 363 | benchRequest(b, gplusGoji, req) 364 | } 365 | func BenchmarkGojiv2_GPlusParam(b *testing.B) { 366 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 367 | benchRequest(b, gplusGojiv2, req) 368 | } 369 | func BenchmarkGoJsonRest_GPlusParam(b *testing.B) { 370 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 371 | benchRequest(b, gplusGoJsonRest, req) 372 | } 373 | func BenchmarkGoRestful_GPlusParam(b *testing.B) { 374 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 375 | benchRequest(b, gplusGoRestful, req) 376 | } 377 | func BenchmarkGorillaMux_GPlusParam(b *testing.B) { 378 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 379 | benchRequest(b, gplusGorillaMux, req) 380 | } 381 | func BenchmarkGowwwRouter_GPlusParam(b *testing.B) { 382 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 383 | benchRequest(b, gplusGowwwRouter, req) 384 | } 385 | func BenchmarkHttpRouter_GPlusParam(b *testing.B) { 386 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 387 | benchRequest(b, gplusHttpRouter, req) 388 | } 389 | func BenchmarkHttpTreeMux_GPlusParam(b *testing.B) { 390 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 391 | benchRequest(b, gplusHttpTreeMux, req) 392 | } 393 | func BenchmarkKocha_GPlusParam(b *testing.B) { 394 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 395 | benchRequest(b, gplusKocha, req) 396 | } 397 | func BenchmarkLARS_GPlusParam(b *testing.B) { 398 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 399 | benchRequest(b, gplusLARS, req) 400 | } 401 | func BenchmarkMacaron_GPlusParam(b *testing.B) { 402 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 403 | benchRequest(b, gplusMacaron, req) 404 | } 405 | func BenchmarkMartini_GPlusParam(b *testing.B) { 406 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 407 | benchRequest(b, gplusMartini, req) 408 | } 409 | func BenchmarkPat_GPlusParam(b *testing.B) { 410 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 411 | benchRequest(b, gplusPat, req) 412 | } 413 | func BenchmarkPossum_GPlusParam(b *testing.B) { 414 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 415 | benchRequest(b, gplusPossum, req) 416 | } 417 | func BenchmarkR2router_GPlusParam(b *testing.B) { 418 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 419 | benchRequest(b, gplusR2router, req) 420 | } 421 | 422 | // func BenchmarkRevel_GPlusParam(b *testing.B) { 423 | // req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 424 | // benchRequest(b, gplusRevel, req) 425 | // } 426 | func BenchmarkRivet_GPlusParam(b *testing.B) { 427 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 428 | benchRequest(b, gplusRivet, req) 429 | } 430 | func BenchmarkTango_GPlusParam(b *testing.B) { 431 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 432 | benchRequest(b, gplusTango, req) 433 | } 434 | func BenchmarkTigerTonic_GPlusParam(b *testing.B) { 435 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 436 | benchRequest(b, gplusTigerTonic, req) 437 | } 438 | func BenchmarkTraffic_GPlusParam(b *testing.B) { 439 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 440 | benchRequest(b, gplusTraffic, req) 441 | } 442 | func BenchmarkVulcan_GPlusParam(b *testing.B) { 443 | req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 444 | benchRequest(b, gplusVulcan, req) 445 | } 446 | 447 | // func BenchmarkZeus_GPlusParam(b *testing.B) { 448 | // req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) 449 | // benchRequest(b, gplusZeus, req) 450 | // } 451 | 452 | // Two Params 453 | func BenchmarkAce_GPlus2Params(b *testing.B) { 454 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 455 | benchRequest(b, gplusAce, req) 456 | } 457 | func BenchmarkAero_GPlus2Params(b *testing.B) { 458 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 459 | benchRequest(b, gplusAero, req) 460 | } 461 | func BenchmarkBear_GPlus2Params(b *testing.B) { 462 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 463 | benchRequest(b, gplusBear, req) 464 | } 465 | func BenchmarkBeego_GPlus2Params(b *testing.B) { 466 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 467 | benchRequest(b, gplusBeego, req) 468 | } 469 | func BenchmarkBone_GPlus2Params(b *testing.B) { 470 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 471 | benchRequest(b, gplusBone, req) 472 | } 473 | func BenchmarkChi_GPlus2Params(b *testing.B) { 474 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 475 | benchRequest(b, gplusChi, req) 476 | } 477 | func BenchmarkCloudyKitRouter_GPlus2Params(b *testing.B) { 478 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 479 | benchRequest(b, gplusCloudyKitRouter, req) 480 | } 481 | func BenchmarkDenco_GPlus2Params(b *testing.B) { 482 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 483 | benchRequest(b, gplusDenco, req) 484 | } 485 | func BenchmarkEcho_GPlus2Params(b *testing.B) { 486 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 487 | benchRequest(b, gplusEcho, req) 488 | } 489 | func BenchmarkGin_GPlus2Params(b *testing.B) { 490 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 491 | benchRequest(b, gplusGin, req) 492 | } 493 | func BenchmarkGocraftWeb_GPlus2Params(b *testing.B) { 494 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 495 | benchRequest(b, gplusGocraftWeb, req) 496 | } 497 | func BenchmarkGoji_GPlus2Params(b *testing.B) { 498 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 499 | benchRequest(b, gplusGoji, req) 500 | } 501 | func BenchmarkGojiv2_GPlus2Params(b *testing.B) { 502 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 503 | benchRequest(b, gplusGojiv2, req) 504 | } 505 | func BenchmarkGoJsonRest_GPlus2Params(b *testing.B) { 506 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 507 | benchRequest(b, gplusGoJsonRest, req) 508 | } 509 | func BenchmarkGoRestful_GPlus2Params(b *testing.B) { 510 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 511 | benchRequest(b, gplusGoRestful, req) 512 | } 513 | func BenchmarkGorillaMux_GPlus2Params(b *testing.B) { 514 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 515 | benchRequest(b, gplusGorillaMux, req) 516 | } 517 | func BenchmarkGowwwRouter_GPlus2Params(b *testing.B) { 518 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 519 | benchRequest(b, gplusGowwwRouter, req) 520 | } 521 | func BenchmarkHttpRouter_GPlus2Params(b *testing.B) { 522 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 523 | benchRequest(b, gplusHttpRouter, req) 524 | } 525 | func BenchmarkHttpTreeMux_GPlus2Params(b *testing.B) { 526 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 527 | benchRequest(b, gplusHttpTreeMux, req) 528 | } 529 | func BenchmarkKocha_GPlus2Params(b *testing.B) { 530 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 531 | benchRequest(b, gplusKocha, req) 532 | } 533 | func BenchmarkLARS_GPlus2Params(b *testing.B) { 534 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 535 | benchRequest(b, gplusLARS, req) 536 | } 537 | func BenchmarkMacaron_GPlus2Params(b *testing.B) { 538 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 539 | benchRequest(b, gplusMacaron, req) 540 | } 541 | func BenchmarkMartini_GPlus2Params(b *testing.B) { 542 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 543 | benchRequest(b, gplusMartini, req) 544 | } 545 | func BenchmarkPat_GPlus2Params(b *testing.B) { 546 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 547 | benchRequest(b, gplusPat, req) 548 | } 549 | func BenchmarkPossum_GPlus2Params(b *testing.B) { 550 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 551 | benchRequest(b, gplusPossum, req) 552 | } 553 | func BenchmarkR2router_GPlus2Params(b *testing.B) { 554 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 555 | benchRequest(b, gplusR2router, req) 556 | } 557 | 558 | // func BenchmarkRevel_GPlus2Params(b *testing.B) { 559 | // req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 560 | // benchRequest(b, gplusRevel, req) 561 | // } 562 | func BenchmarkRivet_GPlus2Params(b *testing.B) { 563 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 564 | benchRequest(b, gplusRivet, req) 565 | } 566 | func BenchmarkTango_GPlus2Params(b *testing.B) { 567 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 568 | benchRequest(b, gplusTango, req) 569 | } 570 | func BenchmarkTigerTonic_GPlus2Params(b *testing.B) { 571 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 572 | benchRequest(b, gplusTigerTonic, req) 573 | } 574 | func BenchmarkTraffic_GPlus2Params(b *testing.B) { 575 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 576 | benchRequest(b, gplusTraffic, req) 577 | } 578 | func BenchmarkVulcan_GPlus2Params(b *testing.B) { 579 | req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 580 | benchRequest(b, gplusVulcan, req) 581 | } 582 | 583 | // func BenchmarkZeus_GPlus2Params(b *testing.B) { 584 | // req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) 585 | // benchRequest(b, gplusZeus, req) 586 | // } 587 | 588 | // All Routes 589 | func BenchmarkAce_GPlusAll(b *testing.B) { 590 | benchRoutes(b, gplusAce, gplusAPI) 591 | } 592 | func BenchmarkAero_GPlusAll(b *testing.B) { 593 | benchRoutes(b, gplusAero, gplusAPI) 594 | } 595 | func BenchmarkBear_GPlusAll(b *testing.B) { 596 | benchRoutes(b, gplusBear, gplusAPI) 597 | } 598 | func BenchmarkBeego_GPlusAll(b *testing.B) { 599 | benchRoutes(b, gplusBeego, gplusAPI) 600 | } 601 | func BenchmarkBone_GPlusAll(b *testing.B) { 602 | benchRoutes(b, gplusBone, gplusAPI) 603 | } 604 | func BenchmarkChi_GPlusAll(b *testing.B) { 605 | benchRoutes(b, gplusChi, gplusAPI) 606 | } 607 | func BenchmarkCloudyKitRouter_GPlusAll(b *testing.B) { 608 | benchRoutes(b, gplusCloudyKitRouter, gplusAPI) 609 | } 610 | func BenchmarkDenco_GPlusAll(b *testing.B) { 611 | benchRoutes(b, gplusDenco, gplusAPI) 612 | } 613 | func BenchmarkEcho_GPlusAll(b *testing.B) { 614 | benchRoutes(b, gplusEcho, gplusAPI) 615 | } 616 | func BenchmarkGin_GPlusAll(b *testing.B) { 617 | benchRoutes(b, gplusGin, gplusAPI) 618 | } 619 | func BenchmarkGocraftWeb_GPlusAll(b *testing.B) { 620 | benchRoutes(b, gplusGocraftWeb, gplusAPI) 621 | } 622 | func BenchmarkGoji_GPlusAll(b *testing.B) { 623 | benchRoutes(b, gplusGoji, gplusAPI) 624 | } 625 | func BenchmarkGojiv2_GPlusAll(b *testing.B) { 626 | benchRoutes(b, gplusGojiv2, gplusAPI) 627 | } 628 | func BenchmarkGoJsonRest_GPlusAll(b *testing.B) { 629 | benchRoutes(b, gplusGoJsonRest, gplusAPI) 630 | } 631 | func BenchmarkGoRestful_GPlusAll(b *testing.B) { 632 | benchRoutes(b, gplusGoRestful, gplusAPI) 633 | } 634 | func BenchmarkGorillaMux_GPlusAll(b *testing.B) { 635 | benchRoutes(b, gplusGorillaMux, gplusAPI) 636 | } 637 | func BenchmarkGowwwRouter_GPlusAll(b *testing.B) { 638 | benchRoutes(b, gplusGowwwRouter, gplusAPI) 639 | } 640 | func BenchmarkHttpRouter_GPlusAll(b *testing.B) { 641 | benchRoutes(b, gplusHttpRouter, gplusAPI) 642 | } 643 | func BenchmarkHttpTreeMux_GPlusAll(b *testing.B) { 644 | benchRoutes(b, gplusHttpTreeMux, gplusAPI) 645 | } 646 | func BenchmarkKocha_GPlusAll(b *testing.B) { 647 | benchRoutes(b, gplusKocha, gplusAPI) 648 | } 649 | func BenchmarkLARS_GPlusAll(b *testing.B) { 650 | benchRoutes(b, gplusLARS, gplusAPI) 651 | } 652 | func BenchmarkMacaron_GPlusAll(b *testing.B) { 653 | benchRoutes(b, gplusMacaron, gplusAPI) 654 | } 655 | func BenchmarkMartini_GPlusAll(b *testing.B) { 656 | benchRoutes(b, gplusMartini, gplusAPI) 657 | } 658 | func BenchmarkPat_GPlusAll(b *testing.B) { 659 | benchRoutes(b, gplusPat, gplusAPI) 660 | } 661 | func BenchmarkPossum_GPlusAll(b *testing.B) { 662 | benchRoutes(b, gplusPossum, gplusAPI) 663 | } 664 | func BenchmarkR2router_GPlusAll(b *testing.B) { 665 | benchRoutes(b, gplusR2router, gplusAPI) 666 | } 667 | 668 | // func BenchmarkRevel_GPlusAll(b *testing.B) { 669 | // benchRoutes(b, gplusRevel, gplusAPI) 670 | // } 671 | func BenchmarkRivet_GPlusAll(b *testing.B) { 672 | benchRoutes(b, gplusRivet, gplusAPI) 673 | } 674 | func BenchmarkTango_GPlusAll(b *testing.B) { 675 | benchRoutes(b, gplusTango, gplusAPI) 676 | } 677 | func BenchmarkTigerTonic_GPlusAll(b *testing.B) { 678 | benchRoutes(b, gplusTigerTonic, gplusAPI) 679 | } 680 | func BenchmarkTraffic_GPlusAll(b *testing.B) { 681 | benchRoutes(b, gplusTraffic, gplusAPI) 682 | } 683 | func BenchmarkVulcan_GPlusAll(b *testing.B) { 684 | benchRoutes(b, gplusVulcan, gplusAPI) 685 | } 686 | 687 | // func BenchmarkZeus_GPlusAll(b *testing.B) { 688 | // benchRoutes(b, gplusZeus, gplusAPI) 689 | // } 690 | -------------------------------------------------------------------------------- /parse_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Julien Schmidt. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be found 3 | // in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "net/http" 9 | "testing" 10 | ) 11 | 12 | // Parse 13 | // https://parse.com/docs/rest#summary 14 | var parseAPI = []route{ 15 | // Objects 16 | {"POST", "/1/classes/:className"}, 17 | {"GET", "/1/classes/:className/:objectId"}, 18 | {"PUT", "/1/classes/:className/:objectId"}, 19 | {"GET", "/1/classes/:className"}, 20 | {"DELETE", "/1/classes/:className/:objectId"}, 21 | 22 | // Users 23 | {"POST", "/1/users"}, 24 | {"GET", "/1/login"}, 25 | {"GET", "/1/users/:objectId"}, 26 | {"PUT", "/1/users/:objectId"}, 27 | {"GET", "/1/users"}, 28 | {"DELETE", "/1/users/:objectId"}, 29 | {"POST", "/1/requestPasswordReset"}, 30 | 31 | // Roles 32 | {"POST", "/1/roles"}, 33 | {"GET", "/1/roles/:objectId"}, 34 | {"PUT", "/1/roles/:objectId"}, 35 | {"GET", "/1/roles"}, 36 | {"DELETE", "/1/roles/:objectId"}, 37 | 38 | // Files 39 | {"POST", "/1/files/:fileName"}, 40 | 41 | // Analytics 42 | {"POST", "/1/events/:eventName"}, 43 | 44 | // Push Notifications 45 | {"POST", "/1/push"}, 46 | 47 | // Installations 48 | {"POST", "/1/installations"}, 49 | {"GET", "/1/installations/:objectId"}, 50 | {"PUT", "/1/installations/:objectId"}, 51 | {"GET", "/1/installations"}, 52 | {"DELETE", "/1/installations/:objectId"}, 53 | 54 | // Cloud Functions 55 | {"POST", "/1/functions"}, 56 | } 57 | 58 | var ( 59 | parseAce http.Handler 60 | parseAero http.Handler 61 | parseBear http.Handler 62 | parseBeego http.Handler 63 | parseBone http.Handler 64 | parseChi http.Handler 65 | parseCloudyKitRouter http.Handler 66 | parseDenco http.Handler 67 | parseEcho http.Handler 68 | parseGin http.Handler 69 | parseGocraftWeb http.Handler 70 | parseGoji http.Handler 71 | parseGojiv2 http.Handler 72 | parseGoJsonRest http.Handler 73 | parseGoRestful http.Handler 74 | parseGorillaMux http.Handler 75 | parseGowwwRouter http.Handler 76 | parseHttpRouter http.Handler 77 | parseHttpTreeMux http.Handler 78 | parseKocha http.Handler 79 | parseLARS http.Handler 80 | parseMacaron http.Handler 81 | parseMartini http.Handler 82 | parsePat http.Handler 83 | parsePossum http.Handler 84 | parseR2router http.Handler 85 | parseRevel http.Handler 86 | parseRivet http.Handler 87 | parseTango http.Handler 88 | parseTigerTonic http.Handler 89 | parseTraffic http.Handler 90 | parseVulcan http.Handler 91 | // parseZeus http.Handler 92 | ) 93 | 94 | func init() { 95 | println("#ParseAPI Routes:", len(parseAPI)) 96 | 97 | calcMem("Ace", func() { 98 | parseAce = loadAce(parseAPI) 99 | }) 100 | calcMem("Aero", func() { 101 | parseAero = loadAero(parseAPI) 102 | }) 103 | calcMem("Bear", func() { 104 | parseBear = loadBear(parseAPI) 105 | }) 106 | calcMem("Beego", func() { 107 | parseBeego = loadBeego(parseAPI) 108 | }) 109 | calcMem("Bone", func() { 110 | parseBone = loadBone(parseAPI) 111 | }) 112 | calcMem("Chi", func() { 113 | parseChi = loadChi(parseAPI) 114 | }) 115 | calcMem("CloudyKitRouter", func() { 116 | parseCloudyKitRouter = loadCloudyKitRouter(parseAPI) 117 | }) 118 | calcMem("Denco", func() { 119 | parseDenco = loadDenco(parseAPI) 120 | }) 121 | calcMem("Echo", func() { 122 | parseEcho = loadEcho(parseAPI) 123 | }) 124 | calcMem("Gin", func() { 125 | parseGin = loadGin(parseAPI) 126 | }) 127 | calcMem("GocraftWeb", func() { 128 | parseGocraftWeb = loadGocraftWeb(parseAPI) 129 | }) 130 | calcMem("Goji", func() { 131 | parseGoji = loadGoji(parseAPI) 132 | }) 133 | calcMem("Gojiv2", func() { 134 | parseGojiv2 = loadGojiv2(parseAPI) 135 | }) 136 | calcMem("GoJsonRest", func() { 137 | parseGoJsonRest = loadGoJsonRest(parseAPI) 138 | }) 139 | calcMem("GoRestful", func() { 140 | parseGoRestful = loadGoRestful(parseAPI) 141 | }) 142 | calcMem("GorillaMux", func() { 143 | parseGorillaMux = loadGorillaMux(parseAPI) 144 | }) 145 | calcMem("GowwwRouter", func() { 146 | parseGowwwRouter = loadGowwwRouter(parseAPI) 147 | }) 148 | calcMem("HttpRouter", func() { 149 | parseHttpRouter = loadHttpRouter(parseAPI) 150 | }) 151 | calcMem("HttpTreeMux", func() { 152 | parseHttpTreeMux = loadHttpTreeMux(parseAPI) 153 | }) 154 | calcMem("Kocha", func() { 155 | parseKocha = loadKocha(parseAPI) 156 | }) 157 | calcMem("LARS", func() { 158 | parseLARS = loadLARS(parseAPI) 159 | }) 160 | calcMem("Macaron", func() { 161 | parseMacaron = loadMacaron(parseAPI) 162 | }) 163 | calcMem("Martini", func() { 164 | parseMartini = loadMartini(parseAPI) 165 | }) 166 | calcMem("Pat", func() { 167 | parsePat = loadPat(parseAPI) 168 | }) 169 | calcMem("Possum", func() { 170 | parsePossum = loadPossum(parseAPI) 171 | }) 172 | calcMem("R2router", func() { 173 | parseR2router = loadR2router(parseAPI) 174 | }) 175 | // calcMem("Revel", func() { 176 | // parseRevel = loadRevel(parseAPI) 177 | // }) 178 | calcMem("Rivet", func() { 179 | parseRivet = loadRivet(parseAPI) 180 | }) 181 | calcMem("Tango", func() { 182 | parseTango = loadTango(parseAPI) 183 | }) 184 | calcMem("TigerTonic", func() { 185 | parseTigerTonic = loadTigerTonic(parseAPI) 186 | }) 187 | calcMem("Traffic", func() { 188 | parseTraffic = loadTraffic(parseAPI) 189 | }) 190 | calcMem("Vulcan", func() { 191 | parseVulcan = loadVulcan(parseAPI) 192 | }) 193 | // calcMem("Zeus", func() { 194 | // parseZeus = loadZeus(parseAPI) 195 | // }) 196 | 197 | println() 198 | } 199 | 200 | // Static 201 | func BenchmarkAce_ParseStatic(b *testing.B) { 202 | req, _ := http.NewRequest("GET", "/1/users", nil) 203 | benchRequest(b, parseAce, req) 204 | } 205 | func BenchmarkAero_ParseStatic(b *testing.B) { 206 | req, _ := http.NewRequest("GET", "/1/users", nil) 207 | benchRequest(b, parseAero, req) 208 | } 209 | func BenchmarkBear_ParseStatic(b *testing.B) { 210 | req, _ := http.NewRequest("GET", "/1/users", nil) 211 | benchRequest(b, parseBear, req) 212 | } 213 | func BenchmarkBeego_ParseStatic(b *testing.B) { 214 | req, _ := http.NewRequest("GET", "/1/users", nil) 215 | benchRequest(b, parseBeego, req) 216 | } 217 | func BenchmarkBone_ParseStatic(b *testing.B) { 218 | req, _ := http.NewRequest("GET", "/1/users", nil) 219 | benchRequest(b, parseBone, req) 220 | } 221 | func BenchmarkChi_ParseStatic(b *testing.B) { 222 | req, _ := http.NewRequest("GET", "/1/users", nil) 223 | benchRequest(b, parseChi, req) 224 | } 225 | func BenchmarkCloudyKitRouter_ParseStatic(b *testing.B) { 226 | req, _ := http.NewRequest("GET", "/1/users", nil) 227 | benchRequest(b, parseCloudyKitRouter, req) 228 | } 229 | func BenchmarkDenco_ParseStatic(b *testing.B) { 230 | req, _ := http.NewRequest("GET", "/1/users", nil) 231 | benchRequest(b, parseDenco, req) 232 | } 233 | func BenchmarkEcho_ParseStatic(b *testing.B) { 234 | req, _ := http.NewRequest("GET", "/1/users", nil) 235 | benchRequest(b, parseEcho, req) 236 | } 237 | func BenchmarkGin_ParseStatic(b *testing.B) { 238 | req, _ := http.NewRequest("GET", "/1/users", nil) 239 | benchRequest(b, parseGin, req) 240 | } 241 | func BenchmarkGocraftWeb_ParseStatic(b *testing.B) { 242 | req, _ := http.NewRequest("GET", "/1/users", nil) 243 | benchRequest(b, parseGocraftWeb, req) 244 | } 245 | func BenchmarkGoji_ParseStatic(b *testing.B) { 246 | req, _ := http.NewRequest("GET", "/1/users", nil) 247 | benchRequest(b, parseGoji, req) 248 | } 249 | func BenchmarkGojiv2_ParseStatic(b *testing.B) { 250 | req, _ := http.NewRequest("GET", "/1/users", nil) 251 | benchRequest(b, parseGojiv2, req) 252 | } 253 | func BenchmarkGoJsonRest_ParseStatic(b *testing.B) { 254 | req, _ := http.NewRequest("GET", "/1/users", nil) 255 | benchRequest(b, parseGoJsonRest, req) 256 | } 257 | func BenchmarkGoRestful_ParseStatic(b *testing.B) { 258 | req, _ := http.NewRequest("GET", "/1/users", nil) 259 | benchRequest(b, parseGoRestful, req) 260 | } 261 | func BenchmarkGorillaMux_ParseStatic(b *testing.B) { 262 | req, _ := http.NewRequest("GET", "/1/users", nil) 263 | benchRequest(b, parseGorillaMux, req) 264 | } 265 | func BenchmarkGowwwRouter_ParseStatic(b *testing.B) { 266 | req, _ := http.NewRequest("GET", "/1/users", nil) 267 | benchRequest(b, parseGowwwRouter, req) 268 | } 269 | func BenchmarkHttpRouter_ParseStatic(b *testing.B) { 270 | req, _ := http.NewRequest("GET", "/1/users", nil) 271 | benchRequest(b, parseHttpRouter, req) 272 | } 273 | func BenchmarkHttpTreeMux_ParseStatic(b *testing.B) { 274 | req, _ := http.NewRequest("GET", "/1/users", nil) 275 | benchRequest(b, parseHttpTreeMux, req) 276 | } 277 | func BenchmarkKocha_ParseStatic(b *testing.B) { 278 | req, _ := http.NewRequest("GET", "/1/users", nil) 279 | benchRequest(b, parseKocha, req) 280 | } 281 | func BenchmarkLARS_ParseStatic(b *testing.B) { 282 | req, _ := http.NewRequest("GET", "/1/users", nil) 283 | benchRequest(b, parseLARS, req) 284 | } 285 | func BenchmarkMacaron_ParseStatic(b *testing.B) { 286 | req, _ := http.NewRequest("GET", "/1/users", nil) 287 | benchRequest(b, parseMacaron, req) 288 | } 289 | func BenchmarkMartini_ParseStatic(b *testing.B) { 290 | req, _ := http.NewRequest("GET", "/1/users", nil) 291 | benchRequest(b, parseMartini, req) 292 | } 293 | func BenchmarkPat_ParseStatic(b *testing.B) { 294 | req, _ := http.NewRequest("GET", "/1/users", nil) 295 | benchRequest(b, parsePat, req) 296 | } 297 | func BenchmarkPossum_ParseStatic(b *testing.B) { 298 | req, _ := http.NewRequest("GET", "/1/users", nil) 299 | benchRequest(b, parsePossum, req) 300 | } 301 | func BenchmarkR2router_ParseStatic(b *testing.B) { 302 | req, _ := http.NewRequest("GET", "/1/users", nil) 303 | benchRequest(b, parseR2router, req) 304 | } 305 | 306 | // func BenchmarkRevel_ParseStatic(b *testing.B) { 307 | // req, _ := http.NewRequest("GET", "/1/users", nil) 308 | // benchRequest(b, parseRevel, req) 309 | // } 310 | func BenchmarkRivet_ParseStatic(b *testing.B) { 311 | req, _ := http.NewRequest("GET", "/1/users", nil) 312 | benchRequest(b, parseRivet, req) 313 | } 314 | func BenchmarkTango_ParseStatic(b *testing.B) { 315 | req, _ := http.NewRequest("GET", "/1/users", nil) 316 | benchRequest(b, parseTango, req) 317 | } 318 | func BenchmarkTigerTonic_ParseStatic(b *testing.B) { 319 | req, _ := http.NewRequest("GET", "/1/users", nil) 320 | benchRequest(b, parseTigerTonic, req) 321 | } 322 | func BenchmarkTraffic_ParseStatic(b *testing.B) { 323 | req, _ := http.NewRequest("GET", "/1/users", nil) 324 | benchRequest(b, parseTraffic, req) 325 | } 326 | func BenchmarkVulcan_ParseStatic(b *testing.B) { 327 | req, _ := http.NewRequest("GET", "/1/users", nil) 328 | benchRequest(b, parseVulcan, req) 329 | } 330 | 331 | // func BenchmarkZeus_ParseStatic(b *testing.B) { 332 | // req, _ := http.NewRequest("GET", "/1/users", nil) 333 | // benchRequest(b, parseZeus, req) 334 | // } 335 | 336 | // One Param 337 | func BenchmarkAce_ParseParam(b *testing.B) { 338 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 339 | benchRequest(b, parseAce, req) 340 | } 341 | func BenchmarkAero_ParseParam(b *testing.B) { 342 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 343 | benchRequest(b, parseAero, req) 344 | } 345 | func BenchmarkBear_ParseParam(b *testing.B) { 346 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 347 | benchRequest(b, parseBear, req) 348 | } 349 | func BenchmarkBeego_ParseParam(b *testing.B) { 350 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 351 | benchRequest(b, parseBeego, req) 352 | } 353 | func BenchmarkBone_ParseParam(b *testing.B) { 354 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 355 | benchRequest(b, parseBone, req) 356 | } 357 | func BenchmarkChi_ParseParam(b *testing.B) { 358 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 359 | benchRequest(b, parseChi, req) 360 | } 361 | func BenchmarkCloudyKitRouter_ParseParam(b *testing.B) { 362 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 363 | benchRequest(b, parseCloudyKitRouter, req) 364 | } 365 | func BenchmarkDenco_ParseParam(b *testing.B) { 366 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 367 | benchRequest(b, parseDenco, req) 368 | } 369 | func BenchmarkEcho_ParseParam(b *testing.B) { 370 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 371 | benchRequest(b, parseEcho, req) 372 | } 373 | func BenchmarkGin_ParseParam(b *testing.B) { 374 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 375 | benchRequest(b, parseGin, req) 376 | } 377 | func BenchmarkGocraftWeb_ParseParam(b *testing.B) { 378 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 379 | benchRequest(b, parseGocraftWeb, req) 380 | } 381 | func BenchmarkGoji_ParseParam(b *testing.B) { 382 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 383 | benchRequest(b, parseGoji, req) 384 | } 385 | func BenchmarkGojiv2_ParseParam(b *testing.B) { 386 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 387 | benchRequest(b, parseGojiv2, req) 388 | } 389 | func BenchmarkGoJsonRest_ParseParam(b *testing.B) { 390 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 391 | benchRequest(b, parseGoJsonRest, req) 392 | } 393 | func BenchmarkGoRestful_ParseParam(b *testing.B) { 394 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 395 | benchRequest(b, parseGoRestful, req) 396 | } 397 | func BenchmarkGorillaMux_ParseParam(b *testing.B) { 398 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 399 | benchRequest(b, parseGorillaMux, req) 400 | } 401 | func BenchmarkGowwwRouter_ParseParam(b *testing.B) { 402 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 403 | benchRequest(b, parseGowwwRouter, req) 404 | } 405 | func BenchmarkHttpRouter_ParseParam(b *testing.B) { 406 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 407 | benchRequest(b, parseHttpRouter, req) 408 | } 409 | func BenchmarkHttpTreeMux_ParseParam(b *testing.B) { 410 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 411 | benchRequest(b, parseHttpTreeMux, req) 412 | } 413 | func BenchmarkKocha_ParseParam(b *testing.B) { 414 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 415 | benchRequest(b, parseKocha, req) 416 | } 417 | func BenchmarkLARS_ParseParam(b *testing.B) { 418 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 419 | benchRequest(b, parseLARS, req) 420 | } 421 | func BenchmarkMacaron_ParseParam(b *testing.B) { 422 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 423 | benchRequest(b, parseMacaron, req) 424 | } 425 | func BenchmarkMartini_ParseParam(b *testing.B) { 426 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 427 | benchRequest(b, parseMartini, req) 428 | } 429 | func BenchmarkPat_ParseParam(b *testing.B) { 430 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 431 | benchRequest(b, parsePat, req) 432 | } 433 | func BenchmarkPossum_ParseParam(b *testing.B) { 434 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 435 | benchRequest(b, parsePossum, req) 436 | } 437 | func BenchmarkR2router_ParseParam(b *testing.B) { 438 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 439 | benchRequest(b, parseR2router, req) 440 | } 441 | 442 | // func BenchmarkRevel_ParseParam(b *testing.B) { 443 | // req, _ := http.NewRequest("GET", "/1/classes/go", nil) 444 | // benchRequest(b, parseRevel, req) 445 | // } 446 | func BenchmarkRivet_ParseParam(b *testing.B) { 447 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 448 | benchRequest(b, parseRivet, req) 449 | } 450 | func BenchmarkTango_ParseParam(b *testing.B) { 451 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 452 | benchRequest(b, parseTango, req) 453 | } 454 | func BenchmarkTigerTonic_ParseParam(b *testing.B) { 455 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 456 | benchRequest(b, parseTigerTonic, req) 457 | } 458 | func BenchmarkTraffic_ParseParam(b *testing.B) { 459 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 460 | benchRequest(b, parseTraffic, req) 461 | } 462 | func BenchmarkVulcan_ParseParam(b *testing.B) { 463 | req, _ := http.NewRequest("GET", "/1/classes/go", nil) 464 | benchRequest(b, parseVulcan, req) 465 | } 466 | 467 | // func BenchmarkZeus_ParseParam(b *testing.B) { 468 | // req, _ := http.NewRequest("GET", "/1/classes/go", nil) 469 | // benchRequest(b, parseZeus, req) 470 | // } 471 | 472 | // Two Params 473 | func BenchmarkAce_Parse2Params(b *testing.B) { 474 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 475 | benchRequest(b, parseAce, req) 476 | } 477 | func BenchmarkAero_Parse2Params(b *testing.B) { 478 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 479 | benchRequest(b, parseAero, req) 480 | } 481 | func BenchmarkBear_Parse2Params(b *testing.B) { 482 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 483 | benchRequest(b, parseBear, req) 484 | } 485 | func BenchmarkBeego_Parse2Params(b *testing.B) { 486 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 487 | benchRequest(b, parseBeego, req) 488 | } 489 | func BenchmarkBone_Parse2Params(b *testing.B) { 490 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 491 | benchRequest(b, parseBone, req) 492 | } 493 | func BenchmarkChi_Parse2Params(b *testing.B) { 494 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 495 | benchRequest(b, parseChi, req) 496 | } 497 | func BenchmarkCloudyKitRouter_Parse2Params(b *testing.B) { 498 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 499 | benchRequest(b, parseCloudyKitRouter, req) 500 | } 501 | func BenchmarkDenco_Parse2Params(b *testing.B) { 502 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 503 | benchRequest(b, parseDenco, req) 504 | } 505 | func BenchmarkEcho_Parse2Params(b *testing.B) { 506 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 507 | benchRequest(b, parseEcho, req) 508 | } 509 | func BenchmarkGin_Parse2Params(b *testing.B) { 510 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 511 | benchRequest(b, parseGin, req) 512 | } 513 | func BenchmarkGocraftWeb_Parse2Params(b *testing.B) { 514 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 515 | benchRequest(b, parseGocraftWeb, req) 516 | } 517 | func BenchmarkGoji_Parse2Params(b *testing.B) { 518 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 519 | benchRequest(b, parseGoji, req) 520 | } 521 | func BenchmarkGojiv2_Parse2Params(b *testing.B) { 522 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 523 | benchRequest(b, parseGojiv2, req) 524 | } 525 | func BenchmarkGoJsonRest_Parse2Params(b *testing.B) { 526 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 527 | benchRequest(b, parseGoJsonRest, req) 528 | } 529 | func BenchmarkGoRestful_Parse2Params(b *testing.B) { 530 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 531 | benchRequest(b, parseGoRestful, req) 532 | } 533 | func BenchmarkGorillaMux_Parse2Params(b *testing.B) { 534 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 535 | benchRequest(b, parseGorillaMux, req) 536 | } 537 | func BenchmarkGowwwRouter_Parse2Params(b *testing.B) { 538 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 539 | benchRequest(b, parseGowwwRouter, req) 540 | } 541 | func BenchmarkHttpRouter_Parse2Params(b *testing.B) { 542 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 543 | benchRequest(b, parseHttpRouter, req) 544 | } 545 | func BenchmarkHttpTreeMux_Parse2Params(b *testing.B) { 546 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 547 | benchRequest(b, parseHttpTreeMux, req) 548 | } 549 | func BenchmarkKocha_Parse2Params(b *testing.B) { 550 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 551 | benchRequest(b, parseKocha, req) 552 | } 553 | func BenchmarkLARS_Parse2Params(b *testing.B) { 554 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 555 | benchRequest(b, parseLARS, req) 556 | } 557 | func BenchmarkMacaron_Parse2Params(b *testing.B) { 558 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 559 | benchRequest(b, parseMacaron, req) 560 | } 561 | func BenchmarkMartini_Parse2Params(b *testing.B) { 562 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 563 | benchRequest(b, parseMartini, req) 564 | } 565 | func BenchmarkPat_Parse2Params(b *testing.B) { 566 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 567 | benchRequest(b, parsePat, req) 568 | } 569 | func BenchmarkPossum_Parse2Params(b *testing.B) { 570 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 571 | benchRequest(b, parsePossum, req) 572 | } 573 | func BenchmarkR2router_Parse2Params(b *testing.B) { 574 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 575 | benchRequest(b, parseR2router, req) 576 | } 577 | 578 | // func BenchmarkRevel_Parse2Params(b *testing.B) { 579 | // req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 580 | // benchRequest(b, parseRevel, req) 581 | // } 582 | func BenchmarkRivet_Parse2Params(b *testing.B) { 583 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 584 | benchRequest(b, parseRivet, req) 585 | } 586 | func BenchmarkTango_Parse2Params(b *testing.B) { 587 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 588 | benchRequest(b, parseTango, req) 589 | } 590 | func BenchmarkTigerTonic_Parse2Params(b *testing.B) { 591 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 592 | benchRequest(b, parseTigerTonic, req) 593 | } 594 | func BenchmarkTraffic_Parse2Params(b *testing.B) { 595 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 596 | benchRequest(b, parseTraffic, req) 597 | } 598 | func BenchmarkVulcan_Parse2Params(b *testing.B) { 599 | req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 600 | benchRequest(b, parseVulcan, req) 601 | } 602 | 603 | // func BenchmarkZeus_Parse2Params(b *testing.B) { 604 | // req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) 605 | // benchRequest(b, parseZeus, req) 606 | // } 607 | 608 | // All Routes 609 | func BenchmarkAce_ParseAll(b *testing.B) { 610 | benchRoutes(b, parseAce, parseAPI) 611 | } 612 | func BenchmarkAero_ParseAll(b *testing.B) { 613 | benchRoutes(b, parseAero, parseAPI) 614 | } 615 | func BenchmarkBear_ParseAll(b *testing.B) { 616 | benchRoutes(b, parseBear, parseAPI) 617 | } 618 | func BenchmarkBeego_ParseAll(b *testing.B) { 619 | benchRoutes(b, parseBeego, parseAPI) 620 | } 621 | func BenchmarkBone_ParseAll(b *testing.B) { 622 | benchRoutes(b, parseBone, parseAPI) 623 | } 624 | func BenchmarkChi_ParseAll(b *testing.B) { 625 | benchRoutes(b, parseChi, parseAPI) 626 | } 627 | func BenchmarkCloudyKitRouter_ParseAll(b *testing.B) { 628 | benchRoutes(b, parseCloudyKitRouter, parseAPI) 629 | } 630 | func BenchmarkDenco_ParseAll(b *testing.B) { 631 | benchRoutes(b, parseDenco, parseAPI) 632 | } 633 | func BenchmarkEcho_ParseAll(b *testing.B) { 634 | benchRoutes(b, parseEcho, parseAPI) 635 | } 636 | func BenchmarkGin_ParseAll(b *testing.B) { 637 | benchRoutes(b, parseGin, parseAPI) 638 | } 639 | func BenchmarkGocraftWeb_ParseAll(b *testing.B) { 640 | benchRoutes(b, parseGocraftWeb, parseAPI) 641 | } 642 | func BenchmarkGoji_ParseAll(b *testing.B) { 643 | benchRoutes(b, parseGoji, parseAPI) 644 | } 645 | func BenchmarkGojiv2_ParseAll(b *testing.B) { 646 | benchRoutes(b, parseGojiv2, parseAPI) 647 | } 648 | func BenchmarkGoJsonRest_ParseAll(b *testing.B) { 649 | benchRoutes(b, parseGoJsonRest, parseAPI) 650 | } 651 | func BenchmarkGoRestful_ParseAll(b *testing.B) { 652 | benchRoutes(b, parseGoRestful, parseAPI) 653 | } 654 | func BenchmarkGorillaMux_ParseAll(b *testing.B) { 655 | benchRoutes(b, parseGorillaMux, parseAPI) 656 | } 657 | func BenchmarkGowwwRouter_ParseAll(b *testing.B) { 658 | benchRoutes(b, parseGowwwRouter, parseAPI) 659 | } 660 | func BenchmarkHttpRouter_ParseAll(b *testing.B) { 661 | benchRoutes(b, parseHttpRouter, parseAPI) 662 | } 663 | func BenchmarkHttpTreeMux_ParseAll(b *testing.B) { 664 | benchRoutes(b, parseHttpTreeMux, parseAPI) 665 | } 666 | func BenchmarkKocha_ParseAll(b *testing.B) { 667 | benchRoutes(b, parseKocha, parseAPI) 668 | } 669 | func BenchmarkLARS_ParseAll(b *testing.B) { 670 | benchRoutes(b, parseLARS, parseAPI) 671 | } 672 | func BenchmarkMacaron_ParseAll(b *testing.B) { 673 | benchRoutes(b, parseMacaron, parseAPI) 674 | } 675 | func BenchmarkMartini_ParseAll(b *testing.B) { 676 | benchRoutes(b, parseMartini, parseAPI) 677 | } 678 | func BenchmarkPat_ParseAll(b *testing.B) { 679 | benchRoutes(b, parsePat, parseAPI) 680 | } 681 | func BenchmarkPossum_ParseAll(b *testing.B) { 682 | benchRoutes(b, parsePossum, parseAPI) 683 | } 684 | func BenchmarkR2router_ParseAll(b *testing.B) { 685 | benchRoutes(b, parseR2router, parseAPI) 686 | } 687 | 688 | // func BenchmarkRevel_ParseAll(b *testing.B) { 689 | // benchRoutes(b, parseRevel, parseAPI) 690 | // } 691 | func BenchmarkRivet_ParseAll(b *testing.B) { 692 | benchRoutes(b, parseRivet, parseAPI) 693 | } 694 | func BenchmarkTango_ParseAll(b *testing.B) { 695 | benchRoutes(b, parseTango, parseAPI) 696 | } 697 | func BenchmarkTigerTonic_ParseAll(b *testing.B) { 698 | benchRoutes(b, parseTigerTonic, parseAPI) 699 | } 700 | func BenchmarkTraffic_ParseAll(b *testing.B) { 701 | benchRoutes(b, parseTraffic, parseAPI) 702 | } 703 | func BenchmarkVulcan_ParseAll(b *testing.B) { 704 | benchRoutes(b, parseVulcan, parseAPI) 705 | } 706 | 707 | // func BenchmarkZeus_ParseAll(b *testing.B) { 708 | // benchRoutes(b, parseZeus, parseAPI) 709 | // } 710 | -------------------------------------------------------------------------------- /routers_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "testing" 7 | ) 8 | 9 | var ( 10 | // load functions of all routers 11 | routers = []struct { 12 | name string 13 | load func(routes []route) http.Handler 14 | }{ 15 | {"Ace", loadAce}, 16 | {"Aero", loadAero}, 17 | {"Bear", loadBear}, 18 | {"Beego", loadBeego}, 19 | {"Bone", loadBone}, 20 | {"Chi", loadChi}, 21 | {"CloudyKitRouter", loadCloudyKitRouter}, 22 | {"Denco", loadDenco}, 23 | {"Echo", loadEcho}, 24 | {"Gin", loadGin}, 25 | {"GocraftWeb", loadGocraftWeb}, 26 | {"Goji", loadGoji}, 27 | {"Gojiv2", loadGojiv2}, 28 | {"GoJsonRest", loadGoJsonRest}, 29 | {"GoRestful", loadGoRestful}, 30 | {"GorillaMux", loadGorillaMux}, 31 | {"GowwwRouter", loadGowwwRouter}, 32 | {"HttpRouter", loadHttpRouter}, 33 | {"HttpTreeMux", loadHttpTreeMux}, 34 | //{"Kocha", loadKocha}, 35 | {"LARS", loadLARS}, 36 | {"Macaron", loadMacaron}, 37 | {"Martini", loadMartini}, 38 | {"Pat", loadPat}, 39 | {"Possum", loadPossum}, 40 | {"R2router", loadR2router}, 41 | // {"Revel", loadRevel}, 42 | {"Rivet", loadRivet}, 43 | //{"Tango", loadTango}, 44 | {"TigerTonic", loadTigerTonic}, 45 | {"Traffic", loadTraffic}, 46 | {"Vulcan", loadVulcan}, 47 | // {"Zeus", loadZeus}, 48 | } 49 | 50 | // all APIs 51 | apis = []struct { 52 | name string 53 | routes []route 54 | }{ 55 | {"GitHub", githubAPI}, 56 | {"GPlus", gplusAPI}, 57 | {"Parse", parseAPI}, 58 | {"Static", staticRoutes}, 59 | } 60 | ) 61 | 62 | func TestRouters(t *testing.T) { 63 | loadTestHandler = true 64 | 65 | for _, router := range routers { 66 | req, _ := http.NewRequest("GET", "/", nil) 67 | u := req.URL 68 | rq := u.RawQuery 69 | 70 | for _, api := range apis { 71 | r := router.load(api.routes) 72 | 73 | for _, route := range api.routes { 74 | w := httptest.NewRecorder() 75 | req.Method = route.method 76 | req.RequestURI = route.path 77 | u.Path = route.path 78 | u.RawQuery = rq 79 | r.ServeHTTP(w, req) 80 | if w.Code != 200 || w.Body.String() != route.path { 81 | t.Errorf( 82 | "%s in API %s: %d - %s; expected %s %s\n", 83 | router.name, api.name, w.Code, w.Body.String(), route.method, route.path, 84 | ) 85 | } 86 | } 87 | } 88 | } 89 | 90 | loadTestHandler = false 91 | } 92 | -------------------------------------------------------------------------------- /static_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Julien Schmidt. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be found 3 | // in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "net/http" 9 | "testing" 10 | ) 11 | 12 | var staticRoutes = []route{ 13 | {"GET", "/"}, 14 | {"GET", "/cmd.html"}, 15 | {"GET", "/code.html"}, 16 | {"GET", "/contrib.html"}, 17 | {"GET", "/contribute.html"}, 18 | {"GET", "/debugging_with_gdb.html"}, 19 | {"GET", "/docs.html"}, 20 | {"GET", "/effective_go.html"}, 21 | {"GET", "/files.log"}, 22 | {"GET", "/gccgo_contribute.html"}, 23 | {"GET", "/gccgo_install.html"}, 24 | {"GET", "/go-logo-black.png"}, 25 | {"GET", "/go-logo-blue.png"}, 26 | {"GET", "/go-logo-white.png"}, 27 | {"GET", "/go1.1.html"}, 28 | {"GET", "/go1.2.html"}, 29 | {"GET", "/go1.html"}, 30 | {"GET", "/go1compat.html"}, 31 | {"GET", "/go_faq.html"}, 32 | {"GET", "/go_mem.html"}, 33 | {"GET", "/go_spec.html"}, 34 | {"GET", "/help.html"}, 35 | {"GET", "/ie.css"}, 36 | {"GET", "/install-source.html"}, 37 | {"GET", "/install.html"}, 38 | {"GET", "/logo-153x55.png"}, 39 | {"GET", "/Makefile"}, 40 | {"GET", "/root.html"}, 41 | {"GET", "/share.png"}, 42 | {"GET", "/sieve.gif"}, 43 | {"GET", "/tos.html"}, 44 | {"GET", "/articles"}, 45 | {"GET", "/articles/go_command.html"}, 46 | {"GET", "/articles/index.html"}, 47 | {"GET", "/articles/wiki"}, 48 | {"GET", "/articles/wiki/edit.html"}, 49 | {"GET", "/articles/wiki/final-noclosure.go"}, 50 | {"GET", "/articles/wiki/final-noerror.go"}, 51 | {"GET", "/articles/wiki/final-parsetemplate.go"}, 52 | {"GET", "/articles/wiki/final-template.go"}, 53 | {"GET", "/articles/wiki/final.go"}, 54 | {"GET", "/articles/wiki/get.go"}, 55 | {"GET", "/articles/wiki/http-sample.go"}, 56 | {"GET", "/articles/wiki/index.html"}, 57 | {"GET", "/articles/wiki/Makefile"}, 58 | {"GET", "/articles/wiki/notemplate.go"}, 59 | {"GET", "/articles/wiki/part1-noerror.go"}, 60 | {"GET", "/articles/wiki/part1.go"}, 61 | {"GET", "/articles/wiki/part2.go"}, 62 | {"GET", "/articles/wiki/part3-errorhandling.go"}, 63 | {"GET", "/articles/wiki/part3.go"}, 64 | {"GET", "/articles/wiki/test.bash"}, 65 | {"GET", "/articles/wiki/test_edit.good"}, 66 | {"GET", "/articles/wiki/test_Test.txt.good"}, 67 | {"GET", "/articles/wiki/test_view.good"}, 68 | {"GET", "/articles/wiki/view.html"}, 69 | {"GET", "/codewalk"}, 70 | {"GET", "/codewalk/codewalk.css"}, 71 | {"GET", "/codewalk/codewalk.js"}, 72 | {"GET", "/codewalk/codewalk.xml"}, 73 | {"GET", "/codewalk/functions.xml"}, 74 | {"GET", "/codewalk/markov.go"}, 75 | {"GET", "/codewalk/markov.xml"}, 76 | {"GET", "/codewalk/pig.go"}, 77 | {"GET", "/codewalk/popout.png"}, 78 | {"GET", "/codewalk/run"}, 79 | {"GET", "/codewalk/sharemem.xml"}, 80 | {"GET", "/codewalk/urlpoll.go"}, 81 | {"GET", "/devel"}, 82 | {"GET", "/devel/release.html"}, 83 | {"GET", "/devel/weekly.html"}, 84 | {"GET", "/gopher"}, 85 | {"GET", "/gopher/appenginegopher.jpg"}, 86 | {"GET", "/gopher/appenginegophercolor.jpg"}, 87 | {"GET", "/gopher/appenginelogo.gif"}, 88 | {"GET", "/gopher/bumper.png"}, 89 | {"GET", "/gopher/bumper192x108.png"}, 90 | {"GET", "/gopher/bumper320x180.png"}, 91 | {"GET", "/gopher/bumper480x270.png"}, 92 | {"GET", "/gopher/bumper640x360.png"}, 93 | {"GET", "/gopher/doc.png"}, 94 | {"GET", "/gopher/frontpage.png"}, 95 | {"GET", "/gopher/gopherbw.png"}, 96 | {"GET", "/gopher/gophercolor.png"}, 97 | {"GET", "/gopher/gophercolor16x16.png"}, 98 | {"GET", "/gopher/help.png"}, 99 | {"GET", "/gopher/pkg.png"}, 100 | {"GET", "/gopher/project.png"}, 101 | {"GET", "/gopher/ref.png"}, 102 | {"GET", "/gopher/run.png"}, 103 | {"GET", "/gopher/talks.png"}, 104 | {"GET", "/gopher/pencil"}, 105 | {"GET", "/gopher/pencil/gopherhat.jpg"}, 106 | {"GET", "/gopher/pencil/gopherhelmet.jpg"}, 107 | {"GET", "/gopher/pencil/gophermega.jpg"}, 108 | {"GET", "/gopher/pencil/gopherrunning.jpg"}, 109 | {"GET", "/gopher/pencil/gopherswim.jpg"}, 110 | {"GET", "/gopher/pencil/gopherswrench.jpg"}, 111 | {"GET", "/play"}, 112 | {"GET", "/play/fib.go"}, 113 | {"GET", "/play/hello.go"}, 114 | {"GET", "/play/life.go"}, 115 | {"GET", "/play/peano.go"}, 116 | {"GET", "/play/pi.go"}, 117 | {"GET", "/play/sieve.go"}, 118 | {"GET", "/play/solitaire.go"}, 119 | {"GET", "/play/tree.go"}, 120 | {"GET", "/progs"}, 121 | {"GET", "/progs/cgo1.go"}, 122 | {"GET", "/progs/cgo2.go"}, 123 | {"GET", "/progs/cgo3.go"}, 124 | {"GET", "/progs/cgo4.go"}, 125 | {"GET", "/progs/defer.go"}, 126 | {"GET", "/progs/defer.out"}, 127 | {"GET", "/progs/defer2.go"}, 128 | {"GET", "/progs/defer2.out"}, 129 | {"GET", "/progs/eff_bytesize.go"}, 130 | {"GET", "/progs/eff_bytesize.out"}, 131 | {"GET", "/progs/eff_qr.go"}, 132 | {"GET", "/progs/eff_sequence.go"}, 133 | {"GET", "/progs/eff_sequence.out"}, 134 | {"GET", "/progs/eff_unused1.go"}, 135 | {"GET", "/progs/eff_unused2.go"}, 136 | {"GET", "/progs/error.go"}, 137 | {"GET", "/progs/error2.go"}, 138 | {"GET", "/progs/error3.go"}, 139 | {"GET", "/progs/error4.go"}, 140 | {"GET", "/progs/go1.go"}, 141 | {"GET", "/progs/gobs1.go"}, 142 | {"GET", "/progs/gobs2.go"}, 143 | {"GET", "/progs/image_draw.go"}, 144 | {"GET", "/progs/image_package1.go"}, 145 | {"GET", "/progs/image_package1.out"}, 146 | {"GET", "/progs/image_package2.go"}, 147 | {"GET", "/progs/image_package2.out"}, 148 | {"GET", "/progs/image_package3.go"}, 149 | {"GET", "/progs/image_package3.out"}, 150 | {"GET", "/progs/image_package4.go"}, 151 | {"GET", "/progs/image_package4.out"}, 152 | {"GET", "/progs/image_package5.go"}, 153 | {"GET", "/progs/image_package5.out"}, 154 | {"GET", "/progs/image_package6.go"}, 155 | {"GET", "/progs/image_package6.out"}, 156 | {"GET", "/progs/interface.go"}, 157 | {"GET", "/progs/interface2.go"}, 158 | {"GET", "/progs/interface2.out"}, 159 | {"GET", "/progs/json1.go"}, 160 | {"GET", "/progs/json2.go"}, 161 | {"GET", "/progs/json2.out"}, 162 | {"GET", "/progs/json3.go"}, 163 | {"GET", "/progs/json4.go"}, 164 | {"GET", "/progs/json5.go"}, 165 | {"GET", "/progs/run"}, 166 | {"GET", "/progs/slices.go"}, 167 | {"GET", "/progs/timeout1.go"}, 168 | {"GET", "/progs/timeout2.go"}, 169 | {"GET", "/progs/update.bash"}, 170 | } 171 | 172 | var ( 173 | staticHttpServeMux http.Handler 174 | 175 | staticAce http.Handler 176 | staticAero http.Handler 177 | staticBear http.Handler 178 | staticBeego http.Handler 179 | staticBone http.Handler 180 | staticChi http.Handler 181 | staticCloudyKitRouter http.Handler 182 | staticDenco http.Handler 183 | staticEcho http.Handler 184 | staticGin http.Handler 185 | staticGocraftWeb http.Handler 186 | staticGoji http.Handler 187 | staticGojiv2 http.Handler 188 | staticGoJsonRest http.Handler 189 | staticGoRestful http.Handler 190 | staticGorillaMux http.Handler 191 | staticGowwwRouter http.Handler 192 | staticHttpRouter http.Handler 193 | staticHttpTreeMux http.Handler 194 | staticKocha http.Handler 195 | staticLARS http.Handler 196 | staticMacaron http.Handler 197 | staticMartini http.Handler 198 | staticPat http.Handler 199 | staticPossum http.Handler 200 | staticR2router http.Handler 201 | // staticRevel http.Handler 202 | staticRivet http.Handler 203 | staticTango http.Handler 204 | staticTigerTonic http.Handler 205 | staticTraffic http.Handler 206 | staticVulcan http.Handler 207 | // staticZeus http.Handler 208 | ) 209 | 210 | func init() { 211 | println("#Static Routes:", len(staticRoutes)) 212 | 213 | calcMem("HttpServeMux", func() { 214 | serveMux := http.NewServeMux() 215 | for _, route := range staticRoutes { 216 | serveMux.HandleFunc(route.path, httpHandlerFunc) 217 | } 218 | staticHttpServeMux = serveMux 219 | }) 220 | 221 | calcMem("Ace", func() { 222 | staticAce = loadAce(staticRoutes) 223 | }) 224 | calcMem("Aero", func() { 225 | staticAero = loadAero(staticRoutes) 226 | }) 227 | calcMem("Bear", func() { 228 | staticBear = loadBear(staticRoutes) 229 | }) 230 | calcMem("Beego", func() { 231 | staticBeego = loadBeego(staticRoutes) 232 | }) 233 | calcMem("Bone", func() { 234 | staticBone = loadBone(staticRoutes) 235 | }) 236 | calcMem("Chi", func() { 237 | staticChi = loadChi(staticRoutes) 238 | }) 239 | calcMem("CloudyKitRouter", func() { 240 | staticCloudyKitRouter = loadCloudyKitRouter(staticRoutes) 241 | }) 242 | calcMem("Denco", func() { 243 | staticDenco = loadDenco(staticRoutes) 244 | }) 245 | calcMem("Echo", func() { 246 | staticEcho = loadEcho(staticRoutes) 247 | }) 248 | calcMem("Gin", func() { 249 | staticGin = loadGin(staticRoutes) 250 | }) 251 | calcMem("GocraftWeb", func() { 252 | staticGocraftWeb = loadGocraftWeb(staticRoutes) 253 | }) 254 | calcMem("Goji", func() { 255 | staticGoji = loadGoji(staticRoutes) 256 | }) 257 | calcMem("Gojiv2", func() { 258 | staticGojiv2 = loadGojiv2(staticRoutes) 259 | }) 260 | calcMem("GoJsonRest", func() { 261 | staticGoJsonRest = loadGoJsonRest(staticRoutes) 262 | }) 263 | calcMem("GoRestful", func() { 264 | staticGoRestful = loadGoRestful(staticRoutes) 265 | }) 266 | calcMem("GorillaMux", func() { 267 | staticGorillaMux = loadGorillaMux(staticRoutes) 268 | }) 269 | calcMem("GowwwRouter", func() { 270 | staticGowwwRouter = loadGowwwRouter(staticRoutes) 271 | }) 272 | calcMem("HttpRouter", func() { 273 | staticHttpRouter = loadHttpRouter(staticRoutes) 274 | }) 275 | calcMem("HttpTreeMux", func() { 276 | staticHttpTreeMux = loadHttpTreeMux(staticRoutes) 277 | }) 278 | calcMem("Kocha", func() { 279 | staticKocha = loadKocha(staticRoutes) 280 | }) 281 | calcMem("LARS", func() { 282 | staticLARS = loadLARS(staticRoutes) 283 | }) 284 | calcMem("Macaron", func() { 285 | staticMacaron = loadMacaron(staticRoutes) 286 | }) 287 | calcMem("Martini", func() { 288 | staticMartini = loadMartini(staticRoutes) 289 | }) 290 | calcMem("Pat", func() { 291 | staticPat = loadPat(staticRoutes) 292 | }) 293 | calcMem("Possum", func() { 294 | staticPossum = loadPossum(staticRoutes) 295 | }) 296 | calcMem("R2router", func() { 297 | staticR2router = loadR2router(staticRoutes) 298 | }) 299 | // calcMem("Revel", func() { 300 | // staticRevel = loadRevel(staticRoutes) 301 | // }) 302 | calcMem("Rivet", func() { 303 | staticRivet = loadRivet(staticRoutes) 304 | }) 305 | calcMem("Tango", func() { 306 | staticTango = loadTango(staticRoutes) 307 | }) 308 | calcMem("TigerTonic", func() { 309 | staticTigerTonic = loadTigerTonic(staticRoutes) 310 | }) 311 | calcMem("Traffic", func() { 312 | staticTraffic = loadTraffic(staticRoutes) 313 | }) 314 | calcMem("Vulcan", func() { 315 | staticVulcan = loadVulcan(staticRoutes) 316 | }) 317 | // calcMem("Zeus", func() { 318 | // staticZeus = loadZeus(staticRoutes) 319 | // }) 320 | 321 | println() 322 | } 323 | 324 | // All routes 325 | 326 | func BenchmarkAce_StaticAll(b *testing.B) { 327 | benchRoutes(b, staticAce, staticRoutes) 328 | } 329 | func BenchmarkAero_StaticAll(b *testing.B) { 330 | benchRoutes(b, staticAero, staticRoutes) 331 | } 332 | func BenchmarkHttpServeMux_StaticAll(b *testing.B) { 333 | benchRoutes(b, staticHttpServeMux, staticRoutes) 334 | } 335 | func BenchmarkBeego_StaticAll(b *testing.B) { 336 | benchRoutes(b, staticBeego, staticRoutes) 337 | } 338 | func BenchmarkBear_StaticAll(b *testing.B) { 339 | benchRoutes(b, staticBear, staticRoutes) 340 | } 341 | func BenchmarkBone_StaticAll(b *testing.B) { 342 | benchRoutes(b, staticBone, staticRoutes) 343 | } 344 | func BenchmarkChi_StaticAll(b *testing.B) { 345 | benchRoutes(b, staticChi, staticRoutes) 346 | } 347 | func BenchmarkCloudyKitRouter_StaticAll(b *testing.B) { 348 | benchRoutes(b, staticCloudyKitRouter, staticRoutes) 349 | } 350 | func BenchmarkDenco_StaticAll(b *testing.B) { 351 | benchRoutes(b, staticDenco, staticRoutes) 352 | } 353 | func BenchmarkEcho_StaticAll(b *testing.B) { 354 | benchRoutes(b, staticEcho, staticRoutes) 355 | } 356 | func BenchmarkGin_StaticAll(b *testing.B) { 357 | benchRoutes(b, staticGin, staticRoutes) 358 | } 359 | func BenchmarkGocraftWeb_StaticAll(b *testing.B) { 360 | benchRoutes(b, staticGocraftWeb, staticRoutes) 361 | } 362 | func BenchmarkGoji_StaticAll(b *testing.B) { 363 | benchRoutes(b, staticGoji, staticRoutes) 364 | } 365 | func BenchmarkGojiv2_StaticAll(b *testing.B) { 366 | benchRoutes(b, staticGojiv2, staticRoutes) 367 | } 368 | func BenchmarkGoJsonRest_StaticAll(b *testing.B) { 369 | benchRoutes(b, staticGoJsonRest, staticRoutes) 370 | } 371 | func BenchmarkGoRestful_StaticAll(b *testing.B) { 372 | benchRoutes(b, staticGoRestful, staticRoutes) 373 | } 374 | func BenchmarkGorillaMux_StaticAll(b *testing.B) { 375 | benchRoutes(b, staticGorillaMux, staticRoutes) 376 | } 377 | func BenchmarkGowwwRouter_StaticAll(b *testing.B) { 378 | benchRoutes(b, staticGowwwRouter, staticRoutes) 379 | } 380 | func BenchmarkHttpRouter_StaticAll(b *testing.B) { 381 | benchRoutes(b, staticHttpRouter, staticRoutes) 382 | } 383 | func BenchmarkHttpTreeMux_StaticAll(b *testing.B) { 384 | benchRoutes(b, staticHttpRouter, staticRoutes) 385 | } 386 | func BenchmarkKocha_StaticAll(b *testing.B) { 387 | benchRoutes(b, staticKocha, staticRoutes) 388 | } 389 | func BenchmarkLARS_StaticAll(b *testing.B) { 390 | benchRoutes(b, staticLARS, staticRoutes) 391 | } 392 | func BenchmarkMacaron_StaticAll(b *testing.B) { 393 | benchRoutes(b, staticMacaron, staticRoutes) 394 | } 395 | func BenchmarkMartini_StaticAll(b *testing.B) { 396 | benchRoutes(b, staticMartini, staticRoutes) 397 | } 398 | func BenchmarkPat_StaticAll(b *testing.B) { 399 | benchRoutes(b, staticPat, staticRoutes) 400 | } 401 | func BenchmarkPossum_StaticAll(b *testing.B) { 402 | benchRoutes(b, staticPossum, staticRoutes) 403 | } 404 | func BenchmarkR2router_StaticAll(b *testing.B) { 405 | benchRoutes(b, staticR2router, staticRoutes) 406 | } 407 | 408 | // func BenchmarkRevel_StaticAll(b *testing.B) { 409 | // benchRoutes(b, staticRevel, staticRoutes) 410 | // } 411 | func BenchmarkRivet_StaticAll(b *testing.B) { 412 | benchRoutes(b, staticRivet, staticRoutes) 413 | } 414 | func BenchmarkTango_StaticAll(b *testing.B) { 415 | benchRoutes(b, staticTango, staticRoutes) 416 | } 417 | func BenchmarkTigerTonic_StaticAll(b *testing.B) { 418 | benchRoutes(b, staticTigerTonic, staticRoutes) 419 | } 420 | func BenchmarkTraffic_StaticAll(b *testing.B) { 421 | benchRoutes(b, staticTraffic, staticRoutes) 422 | } 423 | func BenchmarkVulcan_StaticAll(b *testing.B) { 424 | benchRoutes(b, staticVulcan, staticRoutes) 425 | } 426 | 427 | // func BenchmarkZeus_StaticAll(b *testing.B) { 428 | // benchRoutes(b, staticZeus, staticRoutes) 429 | // } 430 | --------------------------------------------------------------------------------