Echo: A fast HTTP router and micro framework in Go
github.com
github.com
Most APIs seems to respond within 20 to 200ms. Even if you take 1ms to route stuff, what's the point in spending so much time in trying to optimize routing instead of SQL queries, cache layers or developer productivity with a nice ORM ? Trying to squeeze nanoseconds out seems pointless to me at the moment, especially since newcomers to Go end up seeing 20 different routers and might not know where to start.
I'm genuinely wondering.
Every kind of program known to mankind will be implemented if a language remains popular long enough. There are web servers written in awk, but nobody cares because awk isn't compumateguistically threatening to them.
I mean, you could even make a web server/router/framework out of Javascript, but what kind of lunatic would do that?
Many routing implementations are awful, comparing the URL to every single entry instead of using a trie can add up.
> The latest SQLite 3.8.7 alpha version (available on the download page
> http://www.sqlite.org/download.html) is 50% faster than the 3.7.17 release
> from 16 months ago. That is to say, it does 50% more work using the same
> number of CPU cycles.
>
> The 50% faster number above is not about better query plans. This is 50%
> faster at the low-level grunt work of moving bits on and off disk and
> search b-trees. We have achieved this by incorporating hundreds of
> micro-optimizations. Each micro-optimization might improve the performance
> by as little as 0.05%. If we get one that improves performance by 0.25%,
> that is considered a huge win. Each of these optimizations is unmeasurable
> on a real-world system (we have to use cachegrind to get repeatable
> run-times) but if you do enough of them, they add up.I'm not saying I agree, but just one possible answer.
SQL: Pointless without Generics.
Cache layer: Pointless without Generics.
ORM: Pointless even with Generics.It's no 100 mile mountain race, but it is more interesting than just some random HelloWorld router.
Many of our internal services respond in < 5ms while handling thousands of requests per second. 1ms of routing a big deal.
Go 1.5 is going to improve on the GC pauses, but another way of improving it is to just create garbage (by reusing memory). Go doesn't have manual heap allocation and free, but you can easily achieve manual memory management by simple means like handling your own pools.
I'll definitely stick to httprouter as my default starting point, though. The params interface is much nicer, and it's pretty damn good with performance and allocation count: https://github.com/julienschmidt/httprouter
They're sort of cheating by having a pool, and sort of punting with things like "// MaxParam sets the maximum allowed path parameters. Default is 5..."
http://golang.org/src/sync/pool.go
I've programmed without pools or allocations, where everything had statically allocated storage. Both for microcontroller firmware, and telephony software. It's noticeably harder.
I'm always suspicious of usages of `sync.Pool`, it's easy to reuse things that aren't reset properly and end up with subtle coupling between requests.
Looks like a decent implementation, but aesthetically I dislike monolithic "frameworks" (eg: "echo.New()"). The "Go way" is to write small composable libraries, not opaque frameworks. Gorilla would have been a good model to draw inspiration from.
In which case can it make a performance difference if memory is on the stack or somewhere else in memory?
Do you mean it doesn't allocate any memory per request, it just uses pre allocated memory?
It doesn't make any sense.
With things like C-based HTTP or JSON parsers, they will use the same memory space that is being passed to them to par/lex/etc but in this case with a Go library I'm honestly not sure what To does behind the scenes (I haven't looked at the source).