diff --git a/.gitignore b/.gitignore index 1cb99767..28ffa640 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.prof *.res *.test +.idea diff --git a/bench_test.go b/bench_test.go index 52e8c630..4f555a75 100644 --- a/bench_test.go +++ b/bench_test.go @@ -5,6 +5,7 @@ package main import ( + "io" "net/http" "os" "regexp" @@ -96,12 +97,6 @@ func benchRoutes(b *testing.B, router http.Handler, routes []route) { // Micro Benchmarks // Route with Param (no write) -func BenchmarkAce_Param(b *testing.B) { - router := loadAceSingle("GET", "/user/:name", aceHandle) - - r, _ := http.NewRequest("GET", "/user/gordon", nil) - benchRequest(b, router, r) -} func BenchmarkBear_Param(b *testing.B) { router := loadBearSingle("GET", "/user/{name}", bearHandler) @@ -234,14 +229,8 @@ func BenchmarkR2router_Param(b *testing.B) { benchRequest(b, router, r) } -func BenchmarkRevel_Param(b *testing.B) { - router := loadRevelSingle("GET", "/user/:name", "RevelController.Handle") - - r, _ := http.NewRequest("GET", "/user/gordon", nil) - benchRequest(b, router, r) -} -func BenchmarkRivet_Param(b *testing.B) { - router := loadRivetSingle("GET", "/user/:name", rivetHandler) +func BenchmarkRTE_Param(b *testing.B) { + router := loadRTESingle("GET", "/user/:name", func(w http.ResponseWriter, r *http.Request, _ string) {}) r, _ := http.NewRequest("GET", "/user/gordon", nil) benchRequest(b, router, r) @@ -283,12 +272,6 @@ const fiveColon = "/:a/:b/:c/:d/:e" const fiveBrace = "/{a}/{b}/{c}/{d}/{e}" const fiveRoute = "/test/test/test/test/test" -func BenchmarkAce_Param5(b *testing.B) { - router := loadAceSingle("GET", fiveColon, aceHandle) - - r, _ := http.NewRequest("GET", fiveRoute, nil) - benchRequest(b, router, r) -} func BenchmarkBear_Param5(b *testing.B) { router := loadBearSingle("GET", fiveBrace, bearHandler) @@ -420,14 +403,9 @@ func BenchmarkR2router_Param5(b *testing.B) { benchRequest(b, router, r) } -func BenchmarkRevel_Param5(b *testing.B) { - router := loadRevelSingle("GET", fiveColon, "RevelController.Handle") - - r, _ := http.NewRequest("GET", fiveRoute, nil) - benchRequest(b, router, r) -} -func BenchmarkRivet_Param5(b *testing.B) { - router := loadRivetSingle("GET", fiveColon, rivetHandler) +func BenchmarkRTE_Param5(b *testing.B) { + router := loadRTESingle("GET", fiveColon, func(w http.ResponseWriter, r *http.Request, _ [5]string) { + }) r, _ := http.NewRequest("GET", fiveRoute, nil) benchRequest(b, router, r) @@ -469,12 +447,6 @@ const twentyColon = "/:a/:b/:c/:d/:e/:f/:g/:h/:i/:j/:k/:l/:m/:n/:o/:p/:q/:r/:s/: const twentyBrace = "/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}/{j}/{k}/{l}/{m}/{n}/{o}/{p}/{q}/{r}/{s}/{t}" const twentyRoute = "/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t" -func BenchmarkAce_Param20(b *testing.B) { - router := loadAceSingle("GET", twentyColon, aceHandle) - - r, _ := http.NewRequest("GET", twentyRoute, nil) - benchRequest(b, router, r) -} func BenchmarkBear_Param20(b *testing.B) { router := loadBearSingle("GET", twentyBrace, bearHandler) @@ -605,19 +577,6 @@ func BenchmarkR2router_Param20(b *testing.B) { r, _ := http.NewRequest("GET", twentyRoute, nil) benchRequest(b, router, r) } - -func BenchmarkRevel_Param20(b *testing.B) { - router := loadRevelSingle("GET", twentyColon, "RevelController.Handle") - - r, _ := http.NewRequest("GET", twentyRoute, nil) - benchRequest(b, router, r) -} -func BenchmarkRivet_Param20(b *testing.B) { - router := loadRivetSingle("GET", twentyColon, rivetHandler) - - r, _ := http.NewRequest("GET", twentyRoute, nil) - benchRequest(b, router, r) -} func BenchmarkTango_Param20(b *testing.B) { router := loadTangoSingle("GET", twentyColon, tangoHandler) @@ -651,12 +610,6 @@ func BenchmarkVulcan_Param20(b *testing.B) { // } // Route with Param and write -func BenchmarkAce_ParamWrite(b *testing.B) { - router := loadAceSingle("GET", "/user/:name", aceHandleWrite) - - r, _ := http.NewRequest("GET", "/user/gordon", nil) - benchRequest(b, router, r) -} func BenchmarkBear_ParamWrite(b *testing.B) { router := loadBearSingle("GET", "/user/{name}", bearHandlerWrite) @@ -787,16 +740,10 @@ func BenchmarkR2router_ParamWrite(b *testing.B) { r, _ := http.NewRequest("GET", "/user/gordon", nil) benchRequest(b, router, r) } - -func BenchmarkRevel_ParamWrite(b *testing.B) { - router := loadRevelSingle("GET", "/user/:name", "RevelController.HandleWrite") - - r, _ := http.NewRequest("GET", "/user/gordon", nil) - benchRequest(b, router, r) -} -func BenchmarkRivet_ParamWrite(b *testing.B) { - router := loadRivetSingle("GET", "/user/:name", rivetHandlerWrite) - +func BenchmarkRTE_ParamWrite(b *testing.B) { + router := loadRTESingle("GET", "/user/:name", func(w http.ResponseWriter, r *http.Request, name string) { + io.WriteString(w, name) + }) r, _ := http.NewRequest("GET", "/user/gordon", nil) benchRequest(b, router, r) } diff --git a/github_test.go b/github_test.go index bb3f379e..c98096c1 100644 --- a/github_test.go +++ b/github_test.go @@ -274,7 +274,6 @@ var githubAPI = []route{ } var ( - githubAce http.Handler githubBear http.Handler githubBeego http.Handler githubBone http.Handler @@ -296,8 +295,7 @@ var ( githubPat http.Handler githubPossum http.Handler githubR2router http.Handler - githubRevel http.Handler - githubRivet http.Handler + githubRTE http.Handler githubTango http.Handler githubTigerTonic http.Handler githubTraffic http.Handler @@ -308,9 +306,6 @@ var ( func init() { println("#GithubAPI Routes:", len(githubAPI)) - calcMem("Ace", func() { - githubAce = loadAce(githubAPI) - }) calcMem("Bear", func() { githubBear = loadBear(githubAPI) }) @@ -374,11 +369,8 @@ func init() { calcMem("R2router", func() { githubR2router = loadR2router(githubAPI) }) - calcMem("Revel", func() { - githubRevel = loadRevel(githubAPI) - }) - calcMem("Rivet", func() { - githubRivet = loadRivet(githubAPI) + calcMem("RTE", func() { + githubRTE = loadRTE(githubAPI) }) calcMem("Tango", func() { githubTango = loadTango(githubAPI) @@ -400,10 +392,6 @@ func init() { } // Static -func BenchmarkAce_GithubStatic(b *testing.B) { - req, _ := http.NewRequest("GET", "/user/repos", nil) - benchRequest(b, githubAce, req) -} func BenchmarkBear_GithubStatic(b *testing.B) { req, _ := http.NewRequest("GET", "/user/repos", nil) benchRequest(b, githubBear, req) @@ -488,13 +476,9 @@ func BenchmarkR2router_GithubStatic(b *testing.B) { req, _ := http.NewRequest("GET", "/user/repos", nil) benchRequest(b, githubR2router, req) } -func BenchmarkRevel_GithubStatic(b *testing.B) { - req, _ := http.NewRequest("GET", "/user/repos", nil) - benchRequest(b, githubRevel, req) -} -func BenchmarkRivet_GithubStatic(b *testing.B) { +func BenchmarkRTE_GithubStatic(b *testing.B) { req, _ := http.NewRequest("GET", "/user/repos", nil) - benchRequest(b, githubRivet, req) + benchRequest(b, githubRTE, req) } func BenchmarkTango_GithubStatic(b *testing.B) { req, _ := http.NewRequest("GET", "/user/repos", nil) @@ -519,10 +503,6 @@ func BenchmarkVulcan_GithubStatic(b *testing.B) { // } // Param -func BenchmarkAce_GithubParam(b *testing.B) { - req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) - benchRequest(b, githubAce, req) -} func BenchmarkBear_GithubParam(b *testing.B) { req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) benchRequest(b, githubBear, req) @@ -607,13 +587,9 @@ func BenchmarkR2router_GithubParam(b *testing.B) { req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) benchRequest(b, githubR2router, req) } -func BenchmarkRevel_GithubParam(b *testing.B) { - req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) - benchRequest(b, githubRevel, req) -} -func BenchmarkRivet_GithubParam(b *testing.B) { +func BenchmarkRTE_GithubParam(b *testing.B) { req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) - benchRequest(b, githubRivet, req) + benchRequest(b, githubRTE, req) } func BenchmarkTango_GithubParam(b *testing.B) { req, _ := http.NewRequest("GET", "/repos/julienschmidt/httprouter/stargazers", nil) @@ -638,9 +614,6 @@ func BenchmarkVulcan_GithubParam(b *testing.B) { // } // All routes -func BenchmarkAce_GithubAll(b *testing.B) { - benchRoutes(b, githubAce, githubAPI) -} func BenchmarkBear_GithubAll(b *testing.B) { benchRoutes(b, githubBear, githubAPI) } @@ -704,11 +677,8 @@ func BenchmarkPossum_GithubAll(b *testing.B) { func BenchmarkR2router_GithubAll(b *testing.B) { benchRoutes(b, githubR2router, githubAPI) } -func BenchmarkRevel_GithubAll(b *testing.B) { - benchRoutes(b, githubRevel, githubAPI) -} -func BenchmarkRivet_GithubAll(b *testing.B) { - benchRoutes(b, githubRivet, githubAPI) +func BenchmarkRTE_GithubAll(b *testing.B) { + benchRoutes(b, githubRTE, githubAPI) } func BenchmarkTango_GithubAll(b *testing.B) { benchRoutes(b, githubTango, githubAPI) diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..7988b21c --- /dev/null +++ b/go.mod @@ -0,0 +1,60 @@ +module github.com/julienschmidt/go-http-routing-benchmark + +require ( + github.com/Unknwon/com v0.0.0-20190214221849-2d12a219ccaf // indirect + github.com/ant0ine/go-json-rest v3.3.2+incompatible + github.com/astaxie/beego v1.11.1 + github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40 + github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect + github.com/dimfeld/httptreemux v5.0.1+incompatible + github.com/emicklei/go-restful v2.9.0+incompatible + github.com/fsnotify/fsnotify v1.4.7 // indirect + github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 // indirect + github.com/gin-gonic/gin v1.3.0 + github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191 // indirect + github.com/go-macaron/macaron v1.3.2 + github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab + github.com/go-playground/form v3.1.4+incompatible // indirect + github.com/go-playground/lars v4.0.1+incompatible + github.com/go-zoo/bone v0.0.0-20190117145001-d7ce1372afa7 + github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b + github.com/golang/protobuf v1.3.0 // indirect + github.com/gorilla/mux v1.7.0 + github.com/gorilla/websocket v1.4.0 // indirect + github.com/gravitational/trace v0.0.0-20190218181455-5d6afe38af2b // indirect + github.com/jonboulle/clockwork v0.1.0 // indirect + github.com/json-iterator/go v1.1.5 // indirect + github.com/julienschmidt/httprouter v1.2.0 + github.com/jwilner/rte v0.0.0-20190306045212-d83454600b2b + github.com/labstack/echo v3.3.10+incompatible + github.com/labstack/gommon v0.2.8 // indirect + github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de + github.com/lunny/tango v0.5.5 + github.com/mailgun/route v0.0.0-20181101151700-58b44163b968 + github.com/mattn/go-colorable v0.1.1 // indirect + github.com/mattn/go-isatty v0.0.6 // indirect + github.com/mikespook/possum v0.0.0-20170224044927-56d7ebb6470b + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/naoina/denco v0.0.0-20180930074809-8475105a6b4c + github.com/naoina/kocha-urlrouter v0.0.0-20140609163054-ad3a6f079210 + github.com/pilu/config v0.0.0-20131214182432-3eb99e6c0b9a // indirect + github.com/pilu/miniassert v0.0.0-20140522125902-bee63581261a // indirect + github.com/pilu/traffic v0.5.3 + github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a // indirect + github.com/rcrowley/go-tigertonic v0.0.0-20170420123839-fe6b9f080eb7 + github.com/sirupsen/logrus v1.3.0 // indirect + github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff // indirect + github.com/stretchr/testify v1.3.0 // indirect + github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43 // indirect + github.com/ursiform/bear v1.0.1 + github.com/valyala/fasttemplate v1.0.0 // indirect + github.com/vanng822/r2router v0.0.0-20150523112421-1023140a4f30 + github.com/vulcand/predicate v1.1.0 // indirect + github.com/zenazn/goji v0.9.0 + goji.io v2.0.2+incompatible + gopkg.in/fsnotify.v1 v1.4.7 // indirect + gopkg.in/go-playground/assert.v1 v1.2.1 // indirect + gopkg.in/go-playground/validator.v8 v8.18.2 // indirect + gopkg.in/ini.v1 v1.42.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..9a43b8d1 --- /dev/null +++ b/go.sum @@ -0,0 +1,184 @@ +github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Unknwon/com v0.0.0-20190214221849-2d12a219ccaf h1:g3hliyjkDSCLzNlOEc6Bd1dngsiIwPb9LfPuYUv+F+Y= +github.com/Unknwon/com v0.0.0-20190214221849-2d12a219ccaf/go.mod h1:voKvFVpXBJxdIPeqjoJuLK+UVcRlo/JLjeToGxPYu68= +github.com/ant0ine/go-json-rest v3.3.2+incompatible h1:nBixrkLFiDNAW0hauKDLc8yJI6XfrQumWvytE1Hk14E= +github.com/ant0ine/go-json-rest v3.3.2+incompatible/go.mod h1:q6aCt0GfU6LhpBsnZ/2U+mwe+0XB5WStbmwyoPfc+sk= +github.com/astaxie/beego v1.11.1 h1:6DESefxW5oMcRLFRKi53/6exzup/IR6N4EzzS1n6CnQ= +github.com/astaxie/beego v1.11.1/go.mod h1:i69hVzgauOPSw5qeyF4GVZhn7Od0yG5bbCGzmhbWxgQ= +github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ= +github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU= +github.com/belogik/goes v0.0.0-20151229125003-e54d722c3aff/go.mod h1:PhH1ZhyCzHKt4uAasyx+ljRCgoezetRNf59CUtwUkqY= +github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40 h1:y4B3+GPxKlrigF1ha5FFErxK+sr6sWxQovRMzwMhejo= +github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= +github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= +github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE= +github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/couchbase/go-couchbase v0.0.0-20181122212707-3e9b6e1258bb/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U= +github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c= +github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= +github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dimfeld/httptreemux v5.0.1+incompatible h1:Qj3gVcDNoOthBAqftuD596rm4wg/adLLz5xh5CmpiCA= +github.com/dimfeld/httptreemux v5.0.1+incompatible/go.mod h1:rbUlSV+CCpv/SuqUTP/8Bk2O3LyUV436/yaRGkhP6Z0= +github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk= +github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/emicklei/go-restful v2.9.0+incompatible h1:YKhDcF/NL19iSAQcyCATL1MkFXCzxfdaTiuJKr18Ank= +github.com/emicklei/go-restful v2.9.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-gonic/gin v1.3.0 h1:kCmZyPklC0gVdL728E6Aj20uYBJV93nj/TkwBTKhFbs= +github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= +github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191 h1:NjHlg70DuOkcAMqgt0+XA+NHwtu66MkTVVgR4fFWbcI= +github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191/go.mod h1:VFI2o2q9kYsC4o7VP1HrEVosiZZTd+MVT3YZx4gqvJw= +github.com/go-macaron/macaron v1.3.2 h1:sjelXA1ZWCew5y41TxZibMmMgGWVxENrvbWj4jcjYqI= +github.com/go-macaron/macaron v1.3.2/go.mod h1:uDVC25/IzIX76755aUzDNqV4g6BwkAaDivT2Mq38/Gw= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-playground/form v3.1.4+incompatible h1:lvKiHVxE2WvzDIoyMnWcjyiBxKt2+uFJyZcPYWsLnjI= +github.com/go-playground/form v3.1.4+incompatible/go.mod h1:lhcKXfTuhRtIZCIKUeJ0b5F207aeQCPbZU09ScKjwWg= +github.com/go-playground/lars v4.0.1+incompatible h1:d0q8YUzAggHd1iiWgIJKLpHMa2VLEc5a/oCIJLxjHgY= +github.com/go-playground/lars v4.0.1+incompatible/go.mod h1:N3/k870eeSGPNoqbBzTb/PUpQ3uI5ag39Gt8TquOoEo= +github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-zoo/bone v0.0.0-20190117145001-d7ce1372afa7 h1:9j1EAzjykFGj2YY/+Y1TcEQMf5eAEOzbnPUMT9YYb5g= +github.com/go-zoo/bone v0.0.0-20190117145001-d7ce1372afa7/go.mod h1:HI3Lhb7G3UQcAwEhOJ2WyNcsFtQX1WYHa0Hl4OBbhW8= +github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b h1:g2Qcs0B+vOQE1L3a7WQ/JUUSzJnHbTz14qkJSqEWcF4= +github.com/gocraft/web v0.0.0-20190207150652-9707327fb69b/go.mod h1:Ag7UMbZNGrnHwaXPJOUKJIVgx4QOWMOWZngrvsN6qak= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= +github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U= +github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gravitational/trace v0.0.0-20190218181455-5d6afe38af2b h1:FWOyQLIiXINipdqfyB+UEpKlyT3RVpNO6HOR7/Omueg= +github.com/gravitational/trace v0.0.0-20190218181455-5d6afe38af2b/go.mod h1:RvdOUHE4SHqR3oXlFFKnGzms8a5dugHygGw1bqDstYI= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE= +github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/jwilner/rte v0.0.0-20190306045212-d83454600b2b h1:+DlgvIiq4IoxsuWan8ZXkFWG+vyg+Uu7QNp8UAmQY2I= +github.com/jwilner/rte v0.0.0-20190306045212-d83454600b2b/go.mod h1:1JWO5LOn9S4dhsUXCmDu11pKichZXZ5WN0N9flKHiF8= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg= +github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s= +github.com/labstack/gommon v0.2.8 h1:JvRqmeZcfrHC5u6uVleB4NxxNbzx6gpbJiQknDbKQu0= +github.com/labstack/gommon v0.2.8/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de h1:nyxwRdWHAVxpFcDThedEgQ07DbcRc5xgNObtbTp76fk= +github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ= +github.com/lunny/tango v0.5.5 h1:A2m5hRiRyVZtbR9BkrgB8Bswi8L1s97vQglM7DfAtt8= +github.com/lunny/tango v0.5.5/go.mod h1:UYYNJtWM9e9sa0/tuwCZrgmWQu6H5S9/dF2VvgVLchA= +github.com/mailgun/route v0.0.0-20181101151700-58b44163b968 h1:8usGWS9lr8nrFEf4j3mUfZGpXHV2ng3Rmlknh4tp5NE= +github.com/mailgun/route v0.0.0-20181101151700-58b44163b968/go.mod h1:iitUOLTydv/b+q12z6vQ163uUDAZmUa5O2i/fOo7P7M= +github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.6 h1:SrwhHcpV4nWrMGdNcC2kXpMfcBVYGDuTArqyhocJgvA= +github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= +github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mikespook/possum v0.0.0-20170224044927-56d7ebb6470b h1:UpTyMObxdqOJ+QjsW+FBt/grs0MceNRDFVbPH9vx9kI= +github.com/mikespook/possum v0.0.0-20170224044927-56d7ebb6470b/go.mod h1:hNxCw7x0yDbIykxTaAba/7mQm8tgQq5m8i6nxV45ng4= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/naoina/denco v0.0.0-20180930074809-8475105a6b4c h1:OuYPoLEOYbguEn/ihiCTfWM0cjzY5R77CA2vzmx2M8Y= +github.com/naoina/denco v0.0.0-20180930074809-8475105a6b4c/go.mod h1:rJwHqj5scxcViM0kq4dh/d1E9sLBeI1snvkNVX4mQGY= +github.com/naoina/kocha-urlrouter v0.0.0-20140609163054-ad3a6f079210 h1:3U8/mV2GqWsaM9XZZL+sbmF3mDM0rmWZBw8iI/F6Qqg= +github.com/naoina/kocha-urlrouter v0.0.0-20140609163054-ad3a6f079210/go.mod h1:32uT1OraQUMXWWvMR/uLjbcnSPmR38HsVEhlInnJ1CU= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pilu/config v0.0.0-20131214182432-3eb99e6c0b9a h1:Tg4E4cXPZSZyd3H1tJlYo6ZreXV0ZJvE/lorNqyw1AU= +github.com/pilu/config v0.0.0-20131214182432-3eb99e6c0b9a/go.mod h1:9Or9aIl95Kp43zONcHd5tLZGKXb9iLx0pZjau0uJ5zg= +github.com/pilu/miniassert v0.0.0-20140522125902-bee63581261a h1:U8Xgy85P2npR1jqpNF4q9rLSt6kzrOrWubkepc3lWbE= +github.com/pilu/miniassert v0.0.0-20140522125902-bee63581261a/go.mod h1:QKd9TvGj31l6g+MV2PqthhK68d5ZPv/Q2PvtsS0mM3I= +github.com/pilu/traffic v0.5.3 h1:gzDC+/uF1JQNnpcjUhVnw3z9xTBKx9y9FLtdLkHrIbQ= +github.com/pilu/traffic v0.5.3/go.mod h1:pPbakW2fofyQaXrh319Xb9TJpM8gjs/vp+71CztjeK0= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-tigertonic v0.0.0-20170420123839-fe6b9f080eb7 h1:IF6au04LnXfITvXy4gwKKcka4zKYp73RXCEGUACqC/Y= +github.com/rcrowley/go-tigertonic v0.0.0-20170420123839-fe6b9f080eb7/go.mod h1:iFmRpXEuybfivhzfxebaHxO63V+ye2AFJMBk12tZPck= +github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= +github.com/siddontang/ledisdb v0.0.0-20181029004158-becf5f38d373/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg= +github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA= +github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME= +github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= +github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= +github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff h1:86HlEv0yBCry9syNuylzqznKXDK11p6D0DT596yNMys= +github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff/go.mod h1:KSQcGKpxUMHk3nbYzs/tIBAM2iDooCn0BmttHOJEbLs= +github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= +github.com/ugorji/go v1.1.2 h1:JON3E2/GPW2iDNGoSAusl1KDf5TRQ8k8q7Tp097pZGs= +github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= +github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43 h1:BasDe+IErOQKrMVXab7UayvSlIpiyGwRvuX3EKYY7UA= +github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA= +github.com/ursiform/bear v1.0.1 h1:77/y+Hiir4LyLTyUdj0MmxpcW6rYLgeX8WLLxM7e7uY= +github.com/ursiform/bear v1.0.1/go.mod h1:AYsqyNUafOkYwqZV0zZeBkTOpfCRfWCNWvO5CnO7Tv4= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.0 h1:MCROMI9ZxNYyLvdmeQErZcgsUjsxARzi1SnHWYo3TnM= +github.com/valyala/fasttemplate v1.0.0/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/vanng822/r2router v0.0.0-20150523112421-1023140a4f30 h1:fCYIzI798sOjtO9fMZaqF0ldAoYEsMLt2EwX7HdXzu4= +github.com/vanng822/r2router v0.0.0-20150523112421-1023140a4f30/go.mod h1:1BVq8p2jVr55Ost2PkZWDrG86PiJ/0lxqcXoAcGxvWU= +github.com/vulcand/predicate v1.1.0 h1:Gq/uWopa4rx/tnZu2opOSBqHK63Yqlou/SzrbwdJiNg= +github.com/vulcand/predicate v1.1.0/go.mod h1:mlccC5IRBoc2cIFmCB8ZM62I3VDb6p2GXESMHa3CnZg= +github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc= +github.com/zenazn/goji v0.9.0 h1:RSQQAbXGArQ0dIDEq+PI6WqN6if+5KHu6x2Cx/GXLTQ= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +goji.io v2.0.2+incompatible h1:uIssv/elbKRLznFUy3Xj4+2Mz/qKhek/9aZQDUMae7c= +goji.io v2.0.2+incompatible/go.mod h1:sbqFwrtqZACxLBTQcdgVjFh54yGVCvwq8+w49MVMMIk= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85 h1:et7+NAX3lLIk5qUCTA9QelBjGE/NkhzYw/mhnr0s7nI= +golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk= +gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/gplus_test.go b/gplus_test.go index 85344207..41320ac2 100644 --- a/gplus_test.go +++ b/gplus_test.go @@ -36,7 +36,6 @@ var gplusAPI = []route{ } var ( - gplusAce http.Handler gplusBear http.Handler gplusBeego http.Handler gplusBone http.Handler @@ -58,8 +57,7 @@ var ( gplusPat http.Handler gplusPossum http.Handler gplusR2router http.Handler - gplusRevel http.Handler - gplusRivet http.Handler + gplusRTE http.Handler gplusTango http.Handler gplusTigerTonic http.Handler gplusTraffic http.Handler @@ -70,9 +68,6 @@ var ( func init() { println("#GPlusAPI Routes:", len(gplusAPI)) - calcMem("Ace", func() { - gplusAce = loadAce(gplusAPI) - }) calcMem("Bear", func() { gplusBear = loadBear(gplusAPI) }) @@ -136,11 +131,8 @@ func init() { calcMem("R2router", func() { gplusR2router = loadR2router(gplusAPI) }) - calcMem("Revel", func() { - gplusRevel = loadRevel(gplusAPI) - }) - calcMem("Rivet", func() { - gplusRivet = loadRivet(gplusAPI) + calcMem("RTE", func() { + gplusRTE = loadRTE(gplusAPI) }) calcMem("Tango", func() { gplusTango = loadTango(gplusAPI) @@ -162,10 +154,6 @@ func init() { } // Static -func BenchmarkAce_GPlusStatic(b *testing.B) { - req, _ := http.NewRequest("GET", "/people", nil) - benchRequest(b, gplusAce, req) -} func BenchmarkBear_GPlusStatic(b *testing.B) { req, _ := http.NewRequest("GET", "/people", nil) benchRequest(b, gplusBear, req) @@ -250,13 +238,9 @@ func BenchmarkR2router_GPlusStatic(b *testing.B) { req, _ := http.NewRequest("GET", "/people", nil) benchRequest(b, gplusR2router, req) } -func BenchmarkRevel_GPlusStatic(b *testing.B) { +func BenchmarkRTE_GPlusStatic(b *testing.B) { req, _ := http.NewRequest("GET", "/people", nil) - benchRequest(b, gplusRevel, req) -} -func BenchmarkRivet_GPlusStatic(b *testing.B) { - req, _ := http.NewRequest("GET", "/people", nil) - benchRequest(b, gplusRivet, req) + benchRequest(b, gplusRTE, req) } func BenchmarkTango_GPlusStatic(b *testing.B) { req, _ := http.NewRequest("GET", "/people", nil) @@ -281,10 +265,6 @@ func BenchmarkVulcan_GPlusStatic(b *testing.B) { // } // One Param -func BenchmarkAce_GPlusParam(b *testing.B) { - req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) - benchRequest(b, gplusAce, req) -} func BenchmarkBear_GPlusParam(b *testing.B) { req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) benchRequest(b, gplusBear, req) @@ -369,13 +349,9 @@ func BenchmarkR2router_GPlusParam(b *testing.B) { req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) benchRequest(b, gplusR2router, req) } -func BenchmarkRevel_GPlusParam(b *testing.B) { +func BenchmarkRTE_GPlusParam(b *testing.B) { req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) - benchRequest(b, gplusRevel, req) -} -func BenchmarkRivet_GPlusParam(b *testing.B) { - req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) - benchRequest(b, gplusRivet, req) + benchRequest(b, gplusRTE, req) } func BenchmarkTango_GPlusParam(b *testing.B) { req, _ := http.NewRequest("GET", "/people/118051310819094153327", nil) @@ -400,10 +376,6 @@ func BenchmarkVulcan_GPlusParam(b *testing.B) { // } // Two Params -func BenchmarkAce_GPlus2Params(b *testing.B) { - req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) - benchRequest(b, gplusAce, req) -} func BenchmarkBear_GPlus2Params(b *testing.B) { req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) benchRequest(b, gplusBear, req) @@ -488,13 +460,9 @@ func BenchmarkR2router_GPlus2Params(b *testing.B) { req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) benchRequest(b, gplusR2router, req) } -func BenchmarkRevel_GPlus2Params(b *testing.B) { +func BenchmarkRTE_GPlus2Params(b *testing.B) { req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) - benchRequest(b, gplusRevel, req) -} -func BenchmarkRivet_GPlus2Params(b *testing.B) { - req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) - benchRequest(b, gplusRivet, req) + benchRequest(b, gplusRTE, req) } func BenchmarkTango_GPlus2Params(b *testing.B) { req, _ := http.NewRequest("GET", "/people/118051310819094153327/activities/123456789", nil) @@ -519,9 +487,6 @@ func BenchmarkVulcan_GPlus2Params(b *testing.B) { // } // All Routes -func BenchmarkAce_GPlusAll(b *testing.B) { - benchRoutes(b, gplusAce, gplusAPI) -} func BenchmarkBear_GPlusAll(b *testing.B) { benchRoutes(b, gplusBear, gplusAPI) } @@ -585,11 +550,8 @@ func BenchmarkPossum_GPlusAll(b *testing.B) { func BenchmarkR2router_GPlusAll(b *testing.B) { benchRoutes(b, gplusR2router, gplusAPI) } -func BenchmarkRevel_GPlusAll(b *testing.B) { - benchRoutes(b, gplusRevel, gplusAPI) -} -func BenchmarkRivet_GPlusAll(b *testing.B) { - benchRoutes(b, gplusRivet, gplusAPI) +func BenchmarkRTE_GPlusAll(b *testing.B) { + benchRoutes(b, gplusRTE, gplusAPI) } func BenchmarkTango_GPlusAll(b *testing.B) { benchRoutes(b, gplusTango, gplusAPI) diff --git a/parse_test.go b/parse_test.go index 80058da5..ccf795c9 100644 --- a/parse_test.go +++ b/parse_test.go @@ -56,7 +56,6 @@ var parseAPI = []route{ } var ( - parseAce http.Handler parseBear http.Handler parseBeego http.Handler parseBone http.Handler @@ -78,8 +77,7 @@ var ( parsePat http.Handler parsePossum http.Handler parseR2router http.Handler - parseRevel http.Handler - parseRivet http.Handler + parseRTE http.Handler parseTango http.Handler parseTigerTonic http.Handler parseTraffic http.Handler @@ -90,9 +88,6 @@ var ( func init() { println("#ParseAPI Routes:", len(parseAPI)) - calcMem("Ace", func() { - parseAce = loadAce(parseAPI) - }) calcMem("Bear", func() { parseBear = loadBear(parseAPI) }) @@ -156,11 +151,8 @@ func init() { calcMem("R2router", func() { parseR2router = loadR2router(parseAPI) }) - calcMem("Revel", func() { - parseRevel = loadRevel(parseAPI) - }) - calcMem("Rivet", func() { - parseRivet = loadRivet(parseAPI) + calcMem("RTE", func() { + parseRTE = loadRTE(parseAPI) }) calcMem("Tango", func() { parseTango = loadTango(parseAPI) @@ -182,10 +174,6 @@ func init() { } // Static -func BenchmarkAce_ParseStatic(b *testing.B) { - req, _ := http.NewRequest("GET", "/1/users", nil) - benchRequest(b, parseAce, req) -} func BenchmarkBear_ParseStatic(b *testing.B) { req, _ := http.NewRequest("GET", "/1/users", nil) benchRequest(b, parseBear, req) @@ -270,13 +258,9 @@ func BenchmarkR2router_ParseStatic(b *testing.B) { req, _ := http.NewRequest("GET", "/1/users", nil) benchRequest(b, parseR2router, req) } -func BenchmarkRevel_ParseStatic(b *testing.B) { +func BenchmarkRTE_ParseStatic(b *testing.B) { req, _ := http.NewRequest("GET", "/1/users", nil) - benchRequest(b, parseRevel, req) -} -func BenchmarkRivet_ParseStatic(b *testing.B) { - req, _ := http.NewRequest("GET", "/1/users", nil) - benchRequest(b, parseRivet, req) + benchRequest(b, parseRTE, req) } func BenchmarkTango_ParseStatic(b *testing.B) { req, _ := http.NewRequest("GET", "/1/users", nil) @@ -301,10 +285,6 @@ func BenchmarkVulcan_ParseStatic(b *testing.B) { // } // One Param -func BenchmarkAce_ParseParam(b *testing.B) { - req, _ := http.NewRequest("GET", "/1/classes/go", nil) - benchRequest(b, parseAce, req) -} func BenchmarkBear_ParseParam(b *testing.B) { req, _ := http.NewRequest("GET", "/1/classes/go", nil) benchRequest(b, parseBear, req) @@ -389,13 +369,9 @@ func BenchmarkR2router_ParseParam(b *testing.B) { req, _ := http.NewRequest("GET", "/1/classes/go", nil) benchRequest(b, parseR2router, req) } -func BenchmarkRevel_ParseParam(b *testing.B) { +func BenchmarkRTE_ParseParam(b *testing.B) { req, _ := http.NewRequest("GET", "/1/classes/go", nil) - benchRequest(b, parseRevel, req) -} -func BenchmarkRivet_ParseParam(b *testing.B) { - req, _ := http.NewRequest("GET", "/1/classes/go", nil) - benchRequest(b, parseRivet, req) + benchRequest(b, parseRTE, req) } func BenchmarkTango_ParseParam(b *testing.B) { req, _ := http.NewRequest("GET", "/1/classes/go", nil) @@ -420,10 +396,6 @@ func BenchmarkVulcan_ParseParam(b *testing.B) { // } // Two Params -func BenchmarkAce_Parse2Params(b *testing.B) { - req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) - benchRequest(b, parseAce, req) -} func BenchmarkBear_Parse2Params(b *testing.B) { req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) benchRequest(b, parseBear, req) @@ -508,13 +480,9 @@ func BenchmarkR2router_Parse2Params(b *testing.B) { req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) benchRequest(b, parseR2router, req) } -func BenchmarkRevel_Parse2Params(b *testing.B) { +func BenchmarkRTE_Parse2Params(b *testing.B) { req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) - benchRequest(b, parseRevel, req) -} -func BenchmarkRivet_Parse2Params(b *testing.B) { - req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) - benchRequest(b, parseRivet, req) + benchRequest(b, parseRTE, req) } func BenchmarkTango_Parse2Params(b *testing.B) { req, _ := http.NewRequest("GET", "/1/classes/go/123456789", nil) @@ -539,9 +507,6 @@ func BenchmarkVulcan_Parse2Params(b *testing.B) { // } // All Routes -func BenchmarkAce_ParseAll(b *testing.B) { - benchRoutes(b, parseAce, parseAPI) -} func BenchmarkBear_ParseAll(b *testing.B) { benchRoutes(b, parseBear, parseAPI) } @@ -605,11 +570,8 @@ func BenchmarkPossum_ParseAll(b *testing.B) { func BenchmarkR2router_ParseAll(b *testing.B) { benchRoutes(b, parseR2router, parseAPI) } -func BenchmarkRevel_ParseAll(b *testing.B) { - benchRoutes(b, parseRevel, parseAPI) -} -func BenchmarkRivet_ParseAll(b *testing.B) { - benchRoutes(b, parseRivet, parseAPI) +func BenchmarkRTE_ParseAll(b *testing.B) { + benchRoutes(b, parseRTE, parseAPI) } func BenchmarkTango_ParseAll(b *testing.B) { benchRoutes(b, parseTango, parseAPI) diff --git a/routers.go b/routers.go index f9c57cf2..29552b3c 100644 --- a/routers.go +++ b/routers.go @@ -6,12 +6,14 @@ package main import ( "fmt" + "github.com/jwilner/rte" "io" "log" "net/http" "os" "regexp" "runtime" + "strings" // If you add new routers please: // - Keep the benchmark functions etc. alphabetically sorted @@ -43,11 +45,7 @@ import ( "github.com/naoina/kocha-urlrouter" _ "github.com/naoina/kocha-urlrouter/doublearray" "github.com/pilu/traffic" - "github.com/plimble/ace" "github.com/rcrowley/go-tigertonic" - "github.com/revel/revel" - "github.com/robfig/pathtree" - "github.com/typepress/rivet" "github.com/ursiform/bear" "github.com/vanng822/r2router" goji "github.com/zenazn/goji/web" @@ -93,7 +91,6 @@ func init() { initBeego() initGin() initMartini() - initRevel() initTango() initTraffic() } @@ -105,36 +102,6 @@ func httpHandlerFuncTest(w http.ResponseWriter, r *http.Request) { io.WriteString(w, r.RequestURI) } -// Ace -func aceHandle(_ *ace.C) {} - -func aceHandleWrite(c *ace.C) { - io.WriteString(c.Writer, c.Param("name")) -} - -func aceHandleTest(c *ace.C) { - io.WriteString(c.Writer, c.Request.RequestURI) -} - -func loadAce(routes []route) http.Handler { - h := []ace.HandlerFunc{aceHandle} - if loadTestHandler { - h = []ace.HandlerFunc{aceHandleTest} - } - - router := ace.New() - for _, route := range routes { - router.Handle(route.method, route.path, h) - } - return router -} - -func loadAceSingle(method, path string, handle ace.HandlerFunc) http.Handler { - router := ace.New() - router.Handle(method, path, []ace.HandlerFunc{handle}) - return router -} - // bear func bearHandler(_ http.ResponseWriter, _ *http.Request, _ *bear.Context) {} @@ -345,7 +312,7 @@ func echoHandlerTest(c echo.Context) error { func loadEcho(routes []route) http.Handler { var h echo.HandlerFunc = echoHandler - if loadTestHandler { + if loadTestHandler { h = echoHandlerTest } @@ -1130,157 +1097,86 @@ func loadR2routerSingle(method, path string, handler r2router.HandlerFunc) http. return router } -// Revel (Router only) -// In the following code some Revel internals are modelled. -// The original revel code is copyrighted by Rob Figueiredo. -// See https://github.com/revel/revel/blob/master/LICENSE -type RevelController struct { - *revel.Controller - router *revel.Router -} - -func (rc *RevelController) Handle() revel.Result { - return revelResult{} -} - -func (rc *RevelController) HandleWrite() revel.Result { - return rc.RenderText(rc.Params.Get("name")) -} - -func (rc *RevelController) HandleTest() revel.Result { - return rc.RenderText(rc.Request.RequestURI) -} - -type revelResult struct{} - -func (rr revelResult) Apply(req *revel.Request, resp *revel.Response) {} - -func (rc *RevelController) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // Dirty hacks, do NOT copy! - revel.MainRouter = rc.router - - upgrade := r.Header.Get("Upgrade") - if upgrade == "websocket" || upgrade == "Websocket" { - panic("Not implemented") - } else { - var ( - req = revel.NewRequest(r) - resp = revel.NewResponse(w) - c = revel.NewController(req, resp) - ) - req.Websocket = nil - revel.Filters[0](c, revel.Filters[1:]) - if c.Result != nil { - c.Result.Apply(req, resp) - } else if c.Response.Status != 0 { - panic("Not implemented") - } - // Close the Writer if we can - if w, ok := resp.Out.(io.Closer); ok { - w.Close() - } - } -} - -func initRevel() { - // Only use the Revel filters required for this benchmark - revel.Filters = []revel.Filter{ - revel.RouterFilter, - revel.ParamsFilter, - revel.ActionInvoker, - } - - revel.RegisterController((*RevelController)(nil), - []*revel.MethodType{ - { - Name: "Handle", - }, - { - Name: "HandleWrite", - }, - { - Name: "HandleTest", - }, +// RTE +func loadRTE(routes []route) http.Handler { + var rtes []rte.Route + for _, route := range routes { + rtes = append(rtes, rte.Route{ + Method: route.method, + Path: route.path, + Handler: newRteHandler(route.path), }) -} - -func loadRevel(routes []route) http.Handler { - h := "RevelController.Handle" - if loadTestHandler { - h = "RevelController.HandleTest" } - - router := revel.NewRouter("") - - // parseRoutes - var rs []*revel.Route - for _, r := range routes { - rs = append(rs, revel.NewRoute(r.method, r.path, h, "", "", 0)) + return rte.Must(rtes) +} + +func loadRTESingle(method, path string, hndlr interface{}) http.Handler { + return rte.Must(rte.Routes(method+" "+path, hndlr)) +} + +func newRteHandler(path string) interface{} { + if !loadTestHandler { + switch strings.Count(path, ":") { + case 0: + return func(http.ResponseWriter, *http.Request) {} + case 1: + return func(http.ResponseWriter, *http.Request, string) {} + case 2: + return func(http.ResponseWriter, *http.Request, string, string) {} + case 3: + return func(http.ResponseWriter, *http.Request, string, string, string) {} + case 4: + return func(http.ResponseWriter, *http.Request, [4]string) {} + case 5: + return func(http.ResponseWriter, *http.Request, [5]string) {} + case 6: + return func(http.ResponseWriter, *http.Request, [6]string) {} + case 7: + return func(http.ResponseWriter, *http.Request, [7]string) {} + case 8: + return func(http.ResponseWriter, *http.Request, [8]string) {} + } + panic("too many") } - router.Routes = rs - - // updateTree - router.Tree = pathtree.New() - for _, r := range router.Routes { - err := router.Tree.Add(r.TreePath, r) - // Allow GETs to respond to HEAD requests. - if err == nil && r.Method == "GET" { - err = router.Tree.Add("/HEAD"+r.Path, r) + switch strings.Count(path, ":") { + case 0: + return func(w http.ResponseWriter, r *http.Request) { + _, _ = fmt.Fprint(w, r.RequestURI) } - // Error adding a route to the pathtree. - if err != nil { - panic(err) + case 1: + return func(w http.ResponseWriter, r *http.Request, _ string) { + _, _ = fmt.Fprint(w, r.RequestURI) + } + case 2: + return func(w http.ResponseWriter, r *http.Request, _, _ string) { + _, _ = fmt.Fprint(w, r.RequestURI) + } + case 3: + return func(w http.ResponseWriter, r *http.Request, _, _, _ string) { + _, _ = fmt.Fprint(w, r.RequestURI) + } + case 4: + return func(w http.ResponseWriter, r *http.Request, _ [4]string) { + _, _ = fmt.Fprint(w, r.RequestURI) + } + case 5: + return func(w http.ResponseWriter, r *http.Request, _ [5]string) { + _, _ = fmt.Fprint(w, r.RequestURI) + } + case 6: + return func(w http.ResponseWriter, r *http.Request, _ [6]string) { + _, _ = fmt.Fprint(w, r.RequestURI) + } + case 7: + return func(w http.ResponseWriter, r *http.Request, _ [7]string) { + _, _ = fmt.Fprint(w, r.RequestURI) + } + case 8: + return func(w http.ResponseWriter, r *http.Request, _ [8]string) { + _, _ = fmt.Fprint(w, r.RequestURI) } } - - rc := new(RevelController) - rc.router = router - return rc -} - -func loadRevelSingle(method, path, action string) http.Handler { - router := revel.NewRouter("") - - route := revel.NewRoute(method, path, action, "", "", 0) - if err := router.Tree.Add(route.TreePath, route); err != nil { - panic(err) - } - - rc := new(RevelController) - rc.router = router - return rc -} - -// Rivet -func rivetHandler() {} - -func rivetHandlerWrite(c *rivet.Context) { - c.WriteString(c.Get("name")) -} - -func rivetHandlerTest(c *rivet.Context) { - c.WriteString(c.Req.RequestURI) -} - -func loadRivet(routes []route) http.Handler { - var h interface{} = rivetHandler - if loadTestHandler { - h = rivetHandlerTest - } - - router := rivet.New() - for _, route := range routes { - router.Handle(route.method, route.path, h) - } - return router -} - -func loadRivetSingle(method, path string, handler interface{}) http.Handler { - router := rivet.New() - - router.Handle(method, path, handler) - - return router + panic("too many") } // Tango diff --git a/routers_test.go b/routers_test.go index 81e7bdd8..d42f202b 100644 --- a/routers_test.go +++ b/routers_test.go @@ -12,7 +12,6 @@ var ( name string load func(routes []route) http.Handler }{ - {"Ace", loadAce}, {"Bear", loadBear}, {"Beego", loadBeego}, {"Bone", loadBone}, @@ -34,8 +33,7 @@ var ( {"Pat", loadPat}, {"Possum", loadPossum}, {"R2router", loadR2router}, - {"Revel", loadRevel}, - {"Rivet", loadRivet}, + {"RTE", loadRTE}, //{"Tango", loadTango}, {"TigerTonic", loadTigerTonic}, {"Traffic", loadTraffic}, diff --git a/static_test.go b/static_test.go index d3417658..73b0e0f5 100644 --- a/static_test.go +++ b/static_test.go @@ -172,7 +172,6 @@ var staticRoutes = []route{ var ( staticHttpServeMux http.Handler - staticAce http.Handler staticBear http.Handler staticBeego http.Handler staticBone http.Handler @@ -194,8 +193,7 @@ var ( staticPat http.Handler staticPossum http.Handler staticR2router http.Handler - staticRevel http.Handler - staticRivet http.Handler + staticRTE http.Handler staticTango http.Handler staticTigerTonic http.Handler staticTraffic http.Handler @@ -214,9 +212,6 @@ func init() { staticHttpServeMux = serveMux }) - calcMem("Ace", func() { - staticAce = loadAce(staticRoutes) - }) calcMem("Bear", func() { staticBear = loadBear(staticRoutes) }) @@ -280,11 +275,8 @@ func init() { calcMem("R2router", func() { staticR2router = loadR2router(staticRoutes) }) - calcMem("Revel", func() { - staticRevel = loadRevel(staticRoutes) - }) - calcMem("Rivet", func() { - staticRivet = loadRivet(staticRoutes) + calcMem("RTE", func() { + staticRTE = loadRTE(staticRoutes) }) calcMem("Tango", func() { staticTango = loadTango(staticRoutes) @@ -307,9 +299,6 @@ func init() { // All routes -func BenchmarkAce_StaticAll(b *testing.B) { - benchRoutes(b, staticAce, staticRoutes) -} func BenchmarkHttpServeMux_StaticAll(b *testing.B) { benchRoutes(b, staticHttpServeMux, staticRoutes) } @@ -376,11 +365,8 @@ func BenchmarkPossum_StaticAll(b *testing.B) { func BenchmarkR2router_StaticAll(b *testing.B) { benchRoutes(b, staticR2router, staticRoutes) } -func BenchmarkRevel_StaticAll(b *testing.B) { - benchRoutes(b, staticRevel, staticRoutes) -} -func BenchmarkRivet_StaticAll(b *testing.B) { - benchRoutes(b, staticRivet, staticRoutes) +func BenchmarkRTE_StaticAll(b *testing.B) { + benchRoutes(b, staticRTE, staticRoutes) } func BenchmarkTango_StaticAll(b *testing.B) { benchRoutes(b, staticTango, staticRoutes)