Skip to content

Instantly share code, notes, and snippets.

@1xch
Last active August 29, 2015 14:14
Show Gist options
  • Save 1xch/f77e6707fec58b9b628f to your computer and use it in GitHub Desktop.
Save 1xch/f77e6707fec58b9b628f to your computer and use it in GitHub Desktop.
flotilla benchmark
package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
"runtime"
"testing"
"github.com/thrisp/flotilla"
)
const (
fiveColon = "/test/:a/:b/:c/:d/:e"
fiveRoute = "/test/test/test/test/test/test"
twentyColon = "/test/:a/:b/:c/:d/:e/:f/:g/:h/:i/:j/:k/:l/:m/:n/:o/:p/:q/:r/:s/:t"
twentyRoute = "/test/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t"
)
var (
staticRoutes = []route{
{"GET", "/"},
{"GET", "/cmd.html"},
{"GET", "/code.html"},
{"GET", "/contrib.html"},
{"GET", "/contribute.html"},
{"GET", "/debugflotillag_with_gdb.html"},
{"GET", "/docs.html"},
{"GET", "/effective_go.html"},
{"GET", "/files.log"},
{"GET", "/gccgo_contribute.html"},
{"GET", "/gccgo_install.html"},
{"GET", "/go-logo-black.png"},
{"GET", "/go-logo-blue.png"},
{"GET", "/go-logo-white.png"},
{"GET", "/go1.1.html"},
{"GET", "/go1.2.html"},
{"GET", "/go1.html"},
{"GET", "/go1compat.html"},
{"GET", "/go_faq.html"},
{"GET", "/go_mem.html"},
{"GET", "/go_spec.html"},
{"GET", "/help.html"},
{"GET", "/ie.css"},
{"GET", "/install-source.html"},
{"GET", "/install.html"},
{"GET", "/logo-153x55.png"},
{"GET", "/Makefile"},
{"GET", "/root.html"},
{"GET", "/share.png"},
{"GET", "/sieve.gif"},
{"GET", "/tos.html"},
{"GET", "/articles/"},
{"GET", "/articles/go_command.html"},
{"GET", "/articles/index.html"},
{"GET", "/articles/wiki/"},
{"GET", "/articles/wiki/edit.html"},
{"GET", "/articles/wiki/final-noclosure.go"},
{"GET", "/articles/wiki/final-noerror.go"},
{"GET", "/articles/wiki/final-parsetemplate.go"},
{"GET", "/articles/wiki/final-template.go"},
{"GET", "/articles/wiki/final.go"},
{"GET", "/articles/wiki/get.go"},
{"GET", "/articles/wiki/http-sample.go"},
{"GET", "/articles/wiki/index.html"},
{"GET", "/articles/wiki/Makefile"},
{"GET", "/articles/wiki/notemplate.go"},
{"GET", "/articles/wiki/part1-noerror.go"},
{"GET", "/articles/wiki/part1.go"},
{"GET", "/articles/wiki/part2.go"},
{"GET", "/articles/wiki/part3-errorhandling.go"},
{"GET", "/articles/wiki/part3.go"},
{"GET", "/articles/wiki/test.bash"},
{"GET", "/articles/wiki/test_edit.good"},
{"GET", "/articles/wiki/test_Test.txt.good"},
{"GET", "/articles/wiki/test_view.good"},
{"GET", "/articles/wiki/view.html"},
{"GET", "/codewalk/"},
{"GET", "/codewalk/codewalk.css"},
{"GET", "/codewalk/codewalk.js"},
{"GET", "/codewalk/codewalk.xml"},
{"GET", "/codewalk/functions.xml"},
{"GET", "/codewalk/markov.go"},
{"GET", "/codewalk/markov.xml"},
{"GET", "/codewalk/pig.go"},
{"GET", "/codewalk/popout.png"},
{"GET", "/codewalk/run"},
{"GET", "/codewalk/sharemem.xml"},
{"GET", "/codewalk/urlpoll.go"},
{"GET", "/devel/"},
{"GET", "/devel/release.html"},
{"GET", "/devel/weekly.html"},
{"GET", "/gopher/"},
{"GET", "/gopher/appenflotillaegopher.jpg"},
{"GET", "/gopher/appenflotillaegophercolor.jpg"},
{"GET", "/gopher/appenflotillaelogo.gif"},
{"GET", "/gopher/bumper.png"},
{"GET", "/gopher/bumper192x108.png"},
{"GET", "/gopher/bumper320x180.png"},
{"GET", "/gopher/bumper480x270.png"},
{"GET", "/gopher/bumper640x360.png"},
{"GET", "/gopher/doc.png"},
{"GET", "/gopher/frontpage.png"},
{"GET", "/gopher/gopherbw.png"},
{"GET", "/gopher/gophercolor.png"},
{"GET", "/gopher/gophercolor16x16.png"},
{"GET", "/gopher/help.png"},
{"GET", "/gopher/pkg.png"},
{"GET", "/gopher/project.png"},
{"GET", "/gopher/ref.png"},
{"GET", "/gopher/run.png"},
{"GET", "/gopher/talks.png"},
{"GET", "/gopher/pencil/"},
{"GET", "/gopher/pencil/gopherhat.jpg"},
{"GET", "/gopher/pencil/gopherhelmet.jpg"},
{"GET", "/gopher/pencil/gophermega.jpg"},
{"GET", "/gopher/pencil/gopherrunning.jpg"},
{"GET", "/gopher/pencil/gopherswim.jpg"},
{"GET", "/gopher/pencil/gopherswrench.jpg"},
{"GET", "/play/"},
{"GET", "/play/fib.go"},
{"GET", "/play/hello.go"},
{"GET", "/play/life.go"},
{"GET", "/play/peano.go"},
{"GET", "/play/pi.go"},
{"GET", "/play/sieve.go"},
{"GET", "/play/solitaire.go"},
{"GET", "/play/tree.go"},
{"GET", "/progs/"},
{"GET", "/progs/cgo1.go"},
{"GET", "/progs/cgo2.go"},
{"GET", "/progs/cgo3.go"},
{"GET", "/progs/cgo4.go"},
{"GET", "/progs/defer.go"},
{"GET", "/progs/defer.out"},
{"GET", "/progs/defer2.go"},
{"GET", "/progs/defer2.out"},
{"GET", "/progs/eff_bytesize.go"},
{"GET", "/progs/eff_bytesize.out"},
{"GET", "/progs/eff_qr.go"},
{"GET", "/progs/eff_sequence.go"},
{"GET", "/progs/eff_sequence.out"},
{"GET", "/progs/eff_unused1.go"},
{"GET", "/progs/eff_unused2.go"},
{"GET", "/progs/error.go"},
{"GET", "/progs/error2.go"},
{"GET", "/progs/error3.go"},
{"GET", "/progs/error4.go"},
{"GET", "/progs/go1.go"},
{"GET", "/progs/gobs1.go"},
{"GET", "/progs/gobs2.go"},
{"GET", "/progs/image_draw.go"},
{"GET", "/progs/image_package1.go"},
{"GET", "/progs/image_package1.out"},
{"GET", "/progs/image_package2.go"},
{"GET", "/progs/image_package2.out"},
{"GET", "/progs/image_package3.go"},
{"GET", "/progs/image_package3.out"},
{"GET", "/progs/image_package4.go"},
{"GET", "/progs/image_package4.out"},
{"GET", "/progs/image_package5.go"},
{"GET", "/progs/image_package5.out"},
{"GET", "/progs/image_package6.go"},
{"GET", "/progs/image_package6.out"},
{"GET", "/progs/interface.go"},
{"GET", "/progs/interface2.go"},
{"GET", "/progs/interface2.out"},
{"GET", "/progs/json1.go"},
{"GET", "/progs/json2.go"},
{"GET", "/progs/json2.out"},
{"GET", "/progs/json3.go"},
{"GET", "/progs/json4.go"},
{"GET", "/progs/json5.go"},
{"GET", "/progs/run"},
{"GET", "/progs/slices.go"},
{"GET", "/progs/timeout1.go"},
{"GET", "/progs/timeout2.go"},
{"GET", "/progs/update.bash"},
}
parseAPI = []route{
// Objects
{"POST", "/1/classes/:className"},
{"GET", "/1/classes/:className/:objectId"},
{"PUT", "/1/classes/:className/:objectId"},
{"GET", "/1/classes/:className"},
{"DELETE", "/1/classes/:className/:objectId"},
// Users
{"POST", "/1/users"},
{"GET", "/1/loflotilla"},
{"GET", "/1/users/:objectId"},
{"PUT", "/1/users/:objectId"},
{"GET", "/1/users"},
{"DELETE", "/1/users/:objectId"},
{"POST", "/1/requestPasswordReset"},
// Roles
{"POST", "/1/roles"},
{"GET", "/1/roles/:objectId"},
{"PUT", "/1/roles/:objectId"},
{"GET", "/1/roles"},
{"DELETE", "/1/roles/:objectId"},
// Files
{"POST", "/1/files/:fileName"},
// Analytics
{"POST", "/1/events/:eventName"},
// Push Notifications
{"POST", "/1/push"},
// Installations
{"POST", "/1/installations"},
{"GET", "/1/installations/:objectId"},
{"PUT", "/1/installations/:objectId"},
{"GET", "/1/installations"},
{"DELETE", "/1/installations/:objectId"},
// Cloud Functions
{"POST", "/1/functions"},
}
githubAPI = []route{
// OAuth Authorizations
{"GET", "/authorizations"},
{"GET", "/authorizations/:id"},
{"POST", "/authorizations"},
//{"PUT", "/authorizations/clients/:client_id"},
//{"PATCH", "/authorizations/:id"},
{"DELETE", "/authorizations/:id"},
{"GET", "/applications/:client_id/tokens/:access_token"},
{"DELETE", "/applications/:client_id/tokens"},
{"DELETE", "/applications/:client_id/tokens/:access_token"},
// Activity
{"GET", "/events"},
{"GET", "/repos/:owner/:repo/events"},
{"GET", "/networks/:owner/:repo/events"},
{"GET", "/orgs/:org/events"},
{"GET", "/users/:user/received_events"},
{"GET", "/users/:user/received_events/public"},
{"GET", "/users/:user/events"},
{"GET", "/users/:user/events/public"},
{"GET", "/users/:user/events/orgs/:org"},
{"GET", "/feeds"},
{"GET", "/notifications"},
{"GET", "/repos/:owner/:repo/notifications"},
{"PUT", "/notifications"},
{"PUT", "/repos/:owner/:repo/notifications"},
{"GET", "/notifications/threads/:id"},
//{"PATCH", "/notifications/threads/:id"},
{"GET", "/notifications/threads/:id/subscription"},
{"PUT", "/notifications/threads/:id/subscription"},
{"DELETE", "/notifications/threads/:id/subscription"},
{"GET", "/repos/:owner/:repo/stargazers"},
{"GET", "/users/:user/starred"},
{"GET", "/user/starred"},
{"GET", "/user/starred/:owner/:repo"},
{"PUT", "/user/starred/:owner/:repo"},
{"DELETE", "/user/starred/:owner/:repo"},
{"GET", "/repos/:owner/:repo/subscribers"},
{"GET", "/users/:user/subscriptions"},
{"GET", "/user/subscriptions"},
{"GET", "/repos/:owner/:repo/subscription"},
{"PUT", "/repos/:owner/:repo/subscription"},
{"DELETE", "/repos/:owner/:repo/subscription"},
{"GET", "/user/subscriptions/:owner/:repo"},
{"PUT", "/user/subscriptions/:owner/:repo"},
{"DELETE", "/user/subscriptions/:owner/:repo"},
// Gists
{"GET", "/users/:user/gists"},
{"GET", "/gists"},
//{"GET", "/gists/public"},
//{"GET", "/gists/starred"},
{"GET", "/gists/:id"},
{"POST", "/gists"},
//{"PATCH", "/gists/:id"},
{"PUT", "/gists/:id/star"},
{"DELETE", "/gists/:id/star"},
{"GET", "/gists/:id/star"},
{"POST", "/gists/:id/forks"},
{"DELETE", "/gists/:id"},
// Git Data
{"GET", "/repos/:owner/:repo/git/blobs/:sha"},
{"POST", "/repos/:owner/:repo/git/blobs"},
{"GET", "/repos/:owner/:repo/git/commits/:sha"},
{"POST", "/repos/:owner/:repo/git/commits"},
//{"GET", "/repos/:owner/:repo/git/refs/*ref"},
{"GET", "/repos/:owner/:repo/git/refs"},
{"POST", "/repos/:owner/:repo/git/refs"},
//{"PATCH", "/repos/:owner/:repo/git/refs/*ref"},
//{"DELETE", "/repos/:owner/:repo/git/refs/*ref"},
{"GET", "/repos/:owner/:repo/git/tags/:sha"},
{"POST", "/repos/:owner/:repo/git/tags"},
{"GET", "/repos/:owner/:repo/git/trees/:sha"},
{"POST", "/repos/:owner/:repo/git/trees"},
// Issues
{"GET", "/issues"},
{"GET", "/user/issues"},
{"GET", "/orgs/:org/issues"},
{"GET", "/repos/:owner/:repo/issues"},
{"GET", "/repos/:owner/:repo/issues/:number"},
{"POST", "/repos/:owner/:repo/issues"},
//{"PATCH", "/repos/:owner/:repo/issues/:number"},
{"GET", "/repos/:owner/:repo/assignees"},
{"GET", "/repos/:owner/:repo/assignees/:assignee"},
{"GET", "/repos/:owner/:repo/issues/:number/comments"},
//{"GET", "/repos/:owner/:repo/issues/comments"},
//{"GET", "/repos/:owner/:repo/issues/comments/:id"},
{"POST", "/repos/:owner/:repo/issues/:number/comments"},
//{"PATCH", "/repos/:owner/:repo/issues/comments/:id"},
//{"DELETE", "/repos/:owner/:repo/issues/comments/:id"},
{"GET", "/repos/:owner/:repo/issues/:number/events"},
//{"GET", "/repos/:owner/:repo/issues/events"},
//{"GET", "/repos/:owner/:repo/issues/events/:id"},
{"GET", "/repos/:owner/:repo/labels"},
{"GET", "/repos/:owner/:repo/labels/:name"},
{"POST", "/repos/:owner/:repo/labels"},
//{"PATCH", "/repos/:owner/:repo/labels/:name"},
{"DELETE", "/repos/:owner/:repo/labels/:name"},
{"GET", "/repos/:owner/:repo/issues/:number/labels"},
{"POST", "/repos/:owner/:repo/issues/:number/labels"},
{"DELETE", "/repos/:owner/:repo/issues/:number/labels/:name"},
{"PUT", "/repos/:owner/:repo/issues/:number/labels"},
{"DELETE", "/repos/:owner/:repo/issues/:number/labels"},
{"GET", "/repos/:owner/:repo/milestones/:number/labels"},
{"GET", "/repos/:owner/:repo/milestones"},
{"GET", "/repos/:owner/:repo/milestones/:number"},
{"POST", "/repos/:owner/:repo/milestones"},
//{"PATCH", "/repos/:owner/:repo/milestones/:number"},
{"DELETE", "/repos/:owner/:repo/milestones/:number"},
// Miscellaneous
{"GET", "/emojis"},
{"GET", "/gitignore/templates"},
{"GET", "/gitignore/templates/:name"},
{"POST", "/markdown"},
{"POST", "/markdown/raw"},
{"GET", "/meta"},
{"GET", "/rate_limit"},
// Organizations
{"GET", "/users/:user/orgs"},
{"GET", "/user/orgs"},
{"GET", "/orgs/:org"},
//{"PATCH", "/orgs/:org"},
{"GET", "/orgs/:org/members"},
{"GET", "/orgs/:org/members/:user"},
{"DELETE", "/orgs/:org/members/:user"},
{"GET", "/orgs/:org/public_members"},
{"GET", "/orgs/:org/public_members/:user"},
{"PUT", "/orgs/:org/public_members/:user"},
{"DELETE", "/orgs/:org/public_members/:user"},
{"GET", "/orgs/:org/teams"},
{"GET", "/teams/:id"},
{"POST", "/orgs/:org/teams"},
//{"PATCH", "/teams/:id"},
{"DELETE", "/teams/:id"},
{"GET", "/teams/:id/members"},
{"GET", "/teams/:id/members/:user"},
{"PUT", "/teams/:id/members/:user"},
{"DELETE", "/teams/:id/members/:user"},
{"GET", "/teams/:id/repos"},
{"GET", "/teams/:id/repos/:owner/:repo"},
{"PUT", "/teams/:id/repos/:owner/:repo"},
{"DELETE", "/teams/:id/repos/:owner/:repo"},
{"GET", "/user/teams"},
// Pull Requests
{"GET", "/repos/:owner/:repo/pulls"},
{"GET", "/repos/:owner/:repo/pulls/:number"},
{"POST", "/repos/:owner/:repo/pulls"},
//{"PATCH", "/repos/:owner/:repo/pulls/:number"},
{"GET", "/repos/:owner/:repo/pulls/:number/commits"},
{"GET", "/repos/:owner/:repo/pulls/:number/files"},
{"GET", "/repos/:owner/:repo/pulls/:number/merge"},
{"PUT", "/repos/:owner/:repo/pulls/:number/merge"},
{"GET", "/repos/:owner/:repo/pulls/:number/comments"},
//{"GET", "/repos/:owner/:repo/pulls/comments"},
//{"GET", "/repos/:owner/:repo/pulls/comments/:number"},
{"PUT", "/repos/:owner/:repo/pulls/:number/comments"},
//{"PATCH", "/repos/:owner/:repo/pulls/comments/:number"},
//{"DELETE", "/repos/:owner/:repo/pulls/comments/:number"},
// Repositories
{"GET", "/user/repos"},
{"GET", "/users/:user/repos"},
{"GET", "/orgs/:org/repos"},
{"GET", "/repositories"},
{"POST", "/user/repos"},
{"POST", "/orgs/:org/repos"},
{"GET", "/repos/:owner/:repo"},
//{"PATCH", "/repos/:owner/:repo"},
{"GET", "/repos/:owner/:repo/contributors"},
{"GET", "/repos/:owner/:repo/languages"},
{"GET", "/repos/:owner/:repo/teams"},
{"GET", "/repos/:owner/:repo/tags"},
{"GET", "/repos/:owner/:repo/branches"},
{"GET", "/repos/:owner/:repo/branches/:branch"},
{"DELETE", "/repos/:owner/:repo"},
{"GET", "/repos/:owner/:repo/collaborators"},
{"GET", "/repos/:owner/:repo/collaborators/:user"},
{"PUT", "/repos/:owner/:repo/collaborators/:user"},
{"DELETE", "/repos/:owner/:repo/collaborators/:user"},
{"GET", "/repos/:owner/:repo/comments"},
{"GET", "/repos/:owner/:repo/commits/:sha/comments"},
{"POST", "/repos/:owner/:repo/commits/:sha/comments"},
{"GET", "/repos/:owner/:repo/comments/:id"},
//{"PATCH", "/repos/:owner/:repo/comments/:id"},
{"DELETE", "/repos/:owner/:repo/comments/:id"},
{"GET", "/repos/:owner/:repo/commits"},
{"GET", "/repos/:owner/:repo/commits/:sha"},
{"GET", "/repos/:owner/:repo/readme"},
//{"GET", "/repos/:owner/:repo/contents/*path"},
//{"PUT", "/repos/:owner/:repo/contents/*path"},
//{"DELETE", "/repos/:owner/:repo/contents/*path"},
//{"GET", "/repos/:owner/:repo/:archive_format/:ref"},
{"GET", "/repos/:owner/:repo/keys"},
{"GET", "/repos/:owner/:repo/keys/:id"},
{"POST", "/repos/:owner/:repo/keys"},
//{"PATCH", "/repos/:owner/:repo/keys/:id"},
{"DELETE", "/repos/:owner/:repo/keys/:id"},
{"GET", "/repos/:owner/:repo/downloads"},
{"GET", "/repos/:owner/:repo/downloads/:id"},
{"DELETE", "/repos/:owner/:repo/downloads/:id"},
{"GET", "/repos/:owner/:repo/forks"},
{"POST", "/repos/:owner/:repo/forks"},
{"GET", "/repos/:owner/:repo/hooks"},
{"GET", "/repos/:owner/:repo/hooks/:id"},
{"POST", "/repos/:owner/:repo/hooks"},
//{"PATCH", "/repos/:owner/:repo/hooks/:id"},
{"POST", "/repos/:owner/:repo/hooks/:id/tests"},
{"DELETE", "/repos/:owner/:repo/hooks/:id"},
{"POST", "/repos/:owner/:repo/merges"},
{"GET", "/repos/:owner/:repo/releases"},
{"GET", "/repos/:owner/:repo/releases/:id"},
{"POST", "/repos/:owner/:repo/releases"},
//{"PATCH", "/repos/:owner/:repo/releases/:id"},
{"DELETE", "/repos/:owner/:repo/releases/:id"},
{"GET", "/repos/:owner/:repo/releases/:id/assets"},
{"GET", "/repos/:owner/:repo/stats/contributors"},
{"GET", "/repos/:owner/:repo/stats/commit_activity"},
{"GET", "/repos/:owner/:repo/stats/code_frequency"},
{"GET", "/repos/:owner/:repo/stats/participation"},
{"GET", "/repos/:owner/:repo/stats/punch_card"},
{"GET", "/repos/:owner/:repo/statuses/:ref"},
{"POST", "/repos/:owner/:repo/statuses/:ref"},
// Search
{"GET", "/search/repositories"},
{"GET", "/search/code"},
{"GET", "/search/issues"},
{"GET", "/search/users"},
{"GET", "/legacy/issues/search/:owner/:repository/:state/:keyword"},
{"GET", "/legacy/repos/search/:keyword"},
{"GET", "/legacy/user/search/:keyword"},
{"GET", "/legacy/user/email/:email"},
// Users
{"GET", "/users/:user"},
{"GET", "/user"},
//{"PATCH", "/user"},
{"GET", "/users"},
{"GET", "/user/emails"},
{"POST", "/user/emails"},
{"DELETE", "/user/emails"},
{"GET", "/users/:user/followers"},
{"GET", "/user/followers"},
{"GET", "/users/:user/following"},
{"GET", "/user/following"},
{"GET", "/user/following/:user"},
{"GET", "/users/:user/following/:target_user"},
{"PUT", "/user/following/:user"},
{"DELETE", "/user/following/:user"},
{"GET", "/users/:user/keys"},
{"GET", "/user/keys"},
{"GET", "/user/keys/:id"},
{"POST", "/user/keys"},
//{"PATCH", "/user/keys/:id"},
{"DELETE", "/user/keys/:id"},
}
gplusAPI = []route{
// People
{"GET", "/people/:userId"},
{"GET", "/people"},
{"GET", "/activities/:activityId/people/:collection"},
{"GET", "/people/:userId/people/:collection"},
{"GET", "/people/:userId/openIdConnect"},
// Activities
{"GET", "/people/:userId/activities/:collection"},
{"GET", "/activities/:activityId"},
{"GET", "/activities"},
// Comments
{"GET", "/activities/:activityId/comments"},
{"GET", "/comments/:commentId"},
// Moments
{"POST", "/people/:userId/moments/:collection"},
{"GET", "/people/:userId/moments/:collection"},
{"DELETE", "/moments/:id"},
}
staticFlotilla http.Handler
githubFlotilla http.Handler
gplusFlotilla http.Handler
parseFlotilla http.Handler
)
type route struct {
method string
path string
}
type mockResponseWriter struct{}
func (m *mockResponseWriter) Header() (h http.Header) {
return http.Header{}
}
func (m *mockResponseWriter) Write(p []byte) (n int, err error) {
return len(p), nil
}
func (m *mockResponseWriter) WriteString(s string) (n int, err error) {
return len(s), nil
}
func (m *mockResponseWriter) WriteHeader(int) {}
var nullLogger *log.Logger
func calcMem(name string, load func()) {
m := new(runtime.MemStats)
// before
runtime.GC()
runtime.ReadMemStats(m)
before := m.HeapAlloc
load()
// after
runtime.GC()
runtime.ReadMemStats(m)
after := m.HeapAlloc
println(" "+name+":", after-before, "Bytes")
}
func benchRequest(b *testing.B, router http.Handler, r *http.Request) {
w := new(mockResponseWriter)
u := r.URL
rq := u.RawQuery
r.RequestURI = u.RequestURI()
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
u.RawQuery = rq
router.ServeHTTP(w, r)
}
}
func benchRoutes(b *testing.B, router http.Handler, routes []route) {
w := new(mockResponseWriter)
r, _ := http.NewRequest("GET", "/", nil)
u := r.URL
rq := u.RawQuery
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, route := range routes {
r.Method = route.method
r.RequestURI = route.path
u.Path = route.path
u.RawQuery = rq
router.ServeHTTP(w, r)
}
}
}
func flotillaHandle(_ *flotilla.Ctx) {}
func flotillaHandleWrite(c *flotilla.Ctx) {
io.WriteString(c.RW, c.Data["name"].(string))
}
func initFlotilla() {}
func loadFlotilla(rts []route) http.Handler {
router := flotilla.New("loadFlotilla")
for _, rt := range rts {
router.Manage(flotilla.NewRoute(rt.method, rt.path, false, []flotilla.Manage{flotillaHandle}))
}
router.Configure(flotilla.Mode("production", true))
return router
}
func loadFlotillaSingle(method, path string, handle flotilla.Manage) http.Handler {
router := flotilla.New("loadFlotillaSingle")
router.Manage(flotilla.NewRoute(method, path, false, []flotilla.Manage{handle}))
router.Configure(flotilla.Mode("production", true))
return router
}
func BenchmarkFlotilla_Param(b *testing.B) {
router := loadFlotillaSingle("GET", "/user/:name", flotillaHandle)
r, _ := http.NewRequest("GET", "/user/gordon", nil)
benchRequest(b, router, r)
}
func BenchmarkFlotilla_Param5(b *testing.B) {
router := loadFlotillaSingle("GET", fiveColon, flotillaHandle)
r, _ := http.NewRequest("GET", fiveRoute, nil)
benchRequest(b, router, r)
}
func BenchmarkFlotilla_Param20(b *testing.B) {
router := loadFlotillaSingle("GET", twentyColon, flotillaHandle)
r, _ := http.NewRequest("GET", twentyRoute, nil)
benchRequest(b, router, r)
}
func BenchmarkFlotilla_ParamWrite(b *testing.B) {
router := loadFlotillaSingle("GET", "/user/:name", flotillaHandleWrite)
r, _ := http.NewRequest("GET", "/user/gordon", nil)
benchRequest(b, router, r)
}
func BenchmarkFlotilla_StaticAll(b *testing.B) {
benchRoutes(b, staticFlotilla, staticRoutes)
}
func BenchmarkFlotilla_ParseStatic(b *testing.B) {
req, _ := http.NewRequest("GET", "/1/users", nil)
benchRequest(b, parseFlotilla, req)
}
func BenchmarkFlotilla_ParseParam(b *testing.B) {
req, _ := http.NewRequest("GET", "/1/classes/go", nil)
benchRequest(b, parseFlotilla, req)
}
func BenchmarkFlotilla_Parse2Params(b *testing.B) {
req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil)
benchRequest(b, parseFlotilla, req)
}
func BenchmarkFlotilla_ParseAll(b *testing.B) {
benchRoutes(b, parseFlotilla, parseAPI)
}
func BenchmarkFlotilla_GithubStatic(b *testing.B) {
req, _ := http.NewRequest("GET", "/user/repos", nil)
benchRequest(b, githubFlotilla, req)
}
func BenchmarkFlotilla_GithubParam(b *testing.B) {
req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil)
benchRequest(b, githubFlotilla, req)
}
func BenchmarkFlotilla_GithubAll(b *testing.B) {
benchRoutes(b, githubFlotilla, githubAPI)
}
func BenchmarkFlotilla_GPlusStatic(b *testing.B) {
req, _ := http.NewRequest("GET", "/people", nil)
benchRequest(b, gplusFlotilla, req)
}
func BenchmarkFlotilla_GPlusParam(b *testing.B) {
req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil)
benchRequest(b, gplusFlotilla, req)
}
func BenchmarkFlotilla_GPlus2Params(b *testing.B) {
req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil)
benchRequest(b, gplusFlotilla, req)
}
func BenchmarkFlotilla_GPlusAll(b *testing.B) {
benchRoutes(b, gplusFlotilla, gplusAPI)
}
// Usage notice
func main() {
fmt.Println("Usage: go test -bench=. -timeout=20m")
os.Exit(1)
}
func init() {
log.SetOutput(new(mockResponseWriter))
nullLogger = log.New(new(mockResponseWriter), "", 0)
calcMem("Flotilla", func() {
staticFlotilla = loadFlotilla(staticRoutes)
})
calcMem("Flotilla", func() {
githubFlotilla = loadFlotilla(githubAPI)
})
calcMem("Flotilla", func() {
gplusFlotilla = loadFlotilla(gplusAPI)
})
calcMem("Flotilla", func() {
parseFlotilla = loadFlotilla(parseAPI)
})
initFlotilla()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment