6 ms·
Echo: A fast HTTP router and micro framework in Go
- jjbiotech 12y agoWhat do you mean by zero memory allocation? The title seems contradictory. You have to allocate at least some memory for a program to run. Do you mean it doesn't allocate any memory per request, it just uses pre allocated memory?
- gilini 12y agoYeah, seems like a sensationalist title tbh. The project README doesn't giving any info to support that claim as well. It doesn't make any sense.
- ComputerGuru 12y agoThat's standard terminology in libraries, especially in parsers. You don't really care about overhead memory, you're concerned with scaling one the requests start coming in. 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).
- m0th87 12y agoI thought it meant that they were only allocating on the stack instead of the heap, (which would still be wrong terminology-wise) but they're clearly doing heap allocations from the examples: https://github.com/labstack/echo/blob/master/example/main.go https://github.com/labstack/echo/blob/master/example/main.go
- sctb 12y agoWe removed "with zero memory allocation" from the title, because it may be misleading.
- JulianMorrison 12y ago"Constant space" and "zero garbage" perhaps?
- noselasd 12y agoHe means zero _dynamic_ memory allocation.
- AYBABTME 12y agoI'm curious what they did different than httprouter to remove the allocations, or if they trick the benchmark tool by reusing memory with a pool.
- brildum 12y agoLooks like its using a `sync.Pool` to amortize allocations. https://github.com/labstack/echo/blob/master/echo.go#L17 https://github.com/labstack/echo/blob/master/echo.go#L17
- AYBABTME 12y agoI noticed that, I didn't verify where it was used. It's smart, although it cheats the benchmark... kind of. =P 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.
- bkeroack 12y agoIt appears to be storing routes in a tree structure allocated via struct literals in router setup. I'm imagining that if performance is relying on them always being on the stack, that would be an implementation detail of the Go runtime and may change. 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.
- placeybordeaux 12y agoIt seems like it takes most of the important interfaces, in which case I feel like it is close enough to the "Go way".
- detaro 12y ago> I'm imagining that if performance is relying on them always being on the stack In which case can it make a performance difference if memory is on the stack or somewhere else in memory?
- bgentry 12y agoInteresting approach. I guess there are use cases where the small number of allocs of some of the other routers is enough to cause problems. 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 https://github.com/julienschmidt/httprouter
- bigdubs 12y agoWe're also using httprouter and so far have been pretty happy with it. The lack of middleware isn't really an issue, you can inline the key stuff (Gzip, logging) yourself from other sources.
- misframer 12y agoIt isn't too difficult to add basic middleware support. We actually wrote a tiny framework[0] around httprouter for that to use on our API servers. It works pretty well. [0] https://github.com/VividCortex/siesta https://github.com/VividCortex/siesta
- tlb 12y agoIt is interesting and surprising how many allocations per request other frameworks do, from 100s to 10000s. 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..."
- adrusi 12y agoHow is that cheating? That's just how you program without allocations.
- tlb 12y agoPool allocations are still allocations. If you look at the implementation for Pool.get, it works a lot like malloc: http://golang.org/src/sync/pool.go 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.
- conradk 12y agoI don't understand why people keep reinventing routers even though routing doesn't take much time anyways, especially in a compiled language like Go. 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.
- jsprogrammer 12y agoIt's satisfying to roll your own?
- peterwwillis 12y agoBasically. 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?
- gkya 12y agoA router is rather easy to create, so I reckon this sort of easy projects are appealing to people as beginner projects and pet projects, so they implement them and put them on the internet just for kudos or karmas or for merely showin' off to potential employers.
- deleted 12y ago[deleted]
- deleted 12y ago[deleted]
- codexon 12y ago20ms is not fast enough for requests served from memory. Many routing implementations are awful, comparing the URL to every single entry instead of using a trie can add up.
- manucorporat 12y agoI didn't want to release this today... but there we go. Gin will also be a zero allocation http router. https://github.com/gin-gonic/gin/issues/249 https://github.com/gin-gonic/gin/issues/249
- nixarn 12y agoAwesome! Gin is really the best go webframework at the moment. Fast, easy to use and is being maintained and improved upon!
- SuperKlaus 12y agoThat's great!
- mmgutz 12y agoIt would have been nice if the library conformed to http.Handler. That has nothing to do with routing yet whenever a new router comes out, it's non-idiomatic. I'll take free performance anyday but not if I have to rewrite code.
- jrobn 12y agoI'm curious as to why they chose to use a separate echo.Context. Why not create a type with an embedded io.ReaderCloser and a map[string]interface{}. Then replace the req.Body (it's a io.ReaderCloser) with the custom type. You could then write methods that take a http.Request to add/delete/modify the piggy backing context field. No need to have a Context type in your handlers.