Bone – Lightning Fast HTTP Multiplexer in Go
github.com
github.com
https://github.com/julienschmidt/go-http-routing-benchmark
which is a pretty thorough benchmark for Go multiplexers. The author's own framework is always fastest and takes the least amount of memory (there's nothing suspicious about it, it really is the fastest).
The test does a good job of showing just how horribly slow some of these, like Gorilla or Martini, really are. Anyways, Bone seems better than the horrible ones, but it's far from the fastest. A snapshot:
HttpRouter_GithubStatic 20000000 61.7 ns/op 0 B/op 0 allocs/op
Bone_GithubStatic 100000 12441 ns/op 2880 B/op 60 allocs/op
HttpRouter_GithubParam 5000000 341 ns/op 96 B/op 1 allocs/op
Bone_GithubParam 500000 2684 ns/op 853 B/op 12 allocs/op
It also crashed on one of the test (first time I've seen that, so maybe I set it up wrong).The actual way to match routes is important, but something else that a lot of people miss is how to load the Params. If you want to keep the *http.Request interface, there's little choice but to append values to the req.URL.RawQuery so that they can be pulled out via req.URL.Query("...") (which, by the way, everytime time you call Query(), RawQuery gets re-parsed). This is the approach Bone appears to take. It's unfortunate because it results in extra string concatenation. If you want speed, you need to break Go's interface, expose your own req object, and use a pool or something for the params.
Gorilla gives me a lot of comfort, but httprouter might be interesting once I remove other bottlenecks in my app. For most developers, swapping the two is a very premature optimization.
* Routing of requests is done in the context of network IO, perhaps disk IO and likely database accesses. The 500 nanoseconds you shave off your request time are likely not worth the trouble you went through, given that a HTTP request sending the bytes of the header will usually amount to a few hundred microseconds, milliseconds with some body. I'd suggest you attack the problem of performance by profiling bottlenecks, to identify parts of your code that have the greatest impact on the request time.
* The benchmark you wrote is not testing your claim (of fast routing/multiplexing), since the benchmark works against a router with no registered routes. When benchmarketing, I'd suggest creating a realistic scenario, a scenario your users are likely to end up with. In your case, this would likely mean a dozen resources, each with about 5 routes, using all verbs.
This blog post is very useful to begin with optimization work in Go: http://blog.golang.org/profiling-go-programs
Faster code with fewer allocations is always a good thing.
Sorry but how can you really make that claim?
See: https://gdstechnology.blog.gov.uk/2013/12/05/building-a-new-...
http://blog.vulcanproxy.com/trie-based-http-requests-routing...
(normally you'd say "router" or "routing layer" but Go calls their router a "mux" so "mux" and "multiplexer" are the typical term for request routers in Go.)
"Also bone is always gonna be supported and updated."
Superlatives like that decreases the credibility of the author. Always? Really? in a year? five years? ten years?