Last active
August 29, 2015 14:14
-
-
Save 1xch/f77e6707fec58b9b628f to your computer and use it in GitHub Desktop.
flotilla benchmark
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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