github.com/cloudwego/hertz@v0.9.3/pkg/route/routes_timing_test.go (about) 1 /* 2 * Copyright 2022 CloudWeGo Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * The MIT License (MIT) 16 * 17 * Copyright (c) 2014 Manuel MartÃnez-Almeida 18 * 19 * Permission is hereby granted, free of charge, to any person obtaining a copy 20 * of this software and associated documentation files (the "Software"), to deal 21 * in the Software without restriction, including without limitation the rights 22 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 * copies of the Software, and to permit persons to whom the Software is 24 * furnished to do so, subject to the following conditions: 25 * 26 * The above copyright notice and this permission notice shall be included in 27 * all copies or substantial portions of the Software. 28 * 29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 * THE SOFTWARE. 36 * 37 * This file may have been modified by CloudWeGo authors. All CloudWeGo 38 * Modifications are Copyright 2022 CloudWeGo Authors 39 */ 40 41 package route 42 43 import ( 44 "context" 45 "testing" 46 47 "github.com/cloudwego/hertz/pkg/app" 48 "github.com/cloudwego/hertz/pkg/common/config" 49 "github.com/cloudwego/hertz/pkg/protocol" 50 ) 51 52 type Route struct { 53 path string 54 } 55 56 func BenchmarkTree_FindStatic(b *testing.B) { 57 tree := &router{method: "GET", root: &node{}, hasTsrHandler: make(map[string]bool)} 58 59 static := []*Route{ 60 {"/"}, 61 {"/cmd.html"}, 62 {"/code.html"}, 63 {"/contrib.html"}, 64 {"/contribute.html"}, 65 {"/debugging_with_gdb.html"}, 66 {"/docs.html"}, 67 {"/effective_go.html"}, 68 {"/files.log"}, 69 {"/gccgo_contribute.html"}, 70 {"/gccgo_install.html"}, 71 {"/go-logo-black.png"}, 72 {"/go-logo-blue.png"}, 73 {"/go-logo-white.png"}, 74 {"/go1.1.html"}, 75 {"/go1.2.html"}, 76 {"/go1.html"}, 77 {"/go1compat.html"}, 78 {"/go_faq.html"}, 79 {"/go_mem.html"}, 80 {"/go_spec.html"}, 81 {"/help.html"}, 82 {"/ie.css"}, 83 {"/install-source.html"}, 84 {"/install.html"}, 85 {"/logo-153x55.png"}, 86 {"/Makefile"}, 87 {"/root.html"}, 88 {"/share.png"}, 89 {"/sieve.gif"}, 90 {"/tos.html"}, 91 {"/articles/"}, 92 {"/articles/go_command.html"}, 93 {"/articles/index.html"}, 94 {"/articles/wiki/"}, 95 {"/articles/wiki/edit.html"}, 96 {"/articles/wiki/final-noclosure.go"}, 97 {"/articles/wiki/final-noerror.go"}, 98 {"/articles/wiki/final-parsetemplate.go"}, 99 {"/articles/wiki/final-template.go"}, 100 {"/articles/wiki/final.go"}, 101 {"/articles/wiki/get.go"}, 102 {"/articles/wiki/http-sample.go"}, 103 {"/articles/wiki/index.html"}, 104 {"/articles/wiki/Makefile"}, 105 {"/articles/wiki/notemplate.go"}, 106 {"/articles/wiki/part1-noerror.go"}, 107 {"/articles/wiki/part1.go"}, 108 {"/articles/wiki/part2.go"}, 109 {"/articles/wiki/part3-errorhandling.go"}, 110 {"/articles/wiki/part3.go"}, 111 {"/articles/wiki/test.bash"}, 112 {"/articles/wiki/test_edit.good"}, 113 {"/articles/wiki/test_Test.txt.good"}, 114 {"/articles/wiki/test_view.good"}, 115 {"/articles/wiki/view.html"}, 116 {"/codewalk/"}, 117 {"/codewalk/codewalk.css"}, 118 {"/codewalk/codewalk.js"}, 119 {"/codewalk/codewalk.xml"}, 120 {"/codewalk/functions.xml"}, 121 {"/codewalk/markov.go"}, 122 {"/codewalk/markov.xml"}, 123 {"/codewalk/pig.go"}, 124 {"/codewalk/popout.png"}, 125 {"/codewalk/run"}, 126 {"/codewalk/sharemem.xml"}, 127 {"/codewalk/urlpoll.go"}, 128 {"/devel/"}, 129 {"/devel/release.html"}, 130 {"/devel/weekly.html"}, 131 {"/gopher/"}, 132 {"/gopher/appenginegopher.jpg"}, 133 {"/gopher/appenginegophercolor.jpg"}, 134 {"/gopher/appenginelogo.gif"}, 135 {"/gopher/bumper.png"}, 136 {"/gopher/bumper192x108.png"}, 137 {"/gopher/bumper320x180.png"}, 138 {"/gopher/bumper480x270.png"}, 139 {"/gopher/bumper640x360.png"}, 140 {"/gopher/doc.png"}, 141 {"/gopher/frontpage.png"}, 142 {"/gopher/gopherbw.png"}, 143 {"/gopher/gophercolor.png"}, 144 {"/gopher/gophercolor16x16.png"}, 145 {"/gopher/help.png"}, 146 {"/gopher/pkg.png"}, 147 {"/gopher/project.png"}, 148 {"/gopher/ref.png"}, 149 {"/gopher/run.png"}, 150 {"/gopher/talks.png"}, 151 {"/gopher/pencil/"}, 152 {"/gopher/pencil/gopherhat.jpg"}, 153 {"/gopher/pencil/gopherhelmet.jpg"}, 154 {"/gopher/pencil/gophermega.jpg"}, 155 {"/gopher/pencil/gopherrunning.jpg"}, 156 {"/gopher/pencil/gopherswim.jpg"}, 157 {"/gopher/pencil/gopherswrench.jpg"}, 158 {"/play/"}, 159 {"/play/fib.go"}, 160 {"/play/hello.go"}, 161 {"/play/life.go"}, 162 {"/play/peano.go"}, 163 {"/play/pi.go"}, 164 {"/play/sieve.go"}, 165 {"/play/solitaire.go"}, 166 {"/play/tree.go"}, 167 {"/progs/"}, 168 {"/progs/cgo1.go"}, 169 {"/progs/cgo2.go"}, 170 {"/progs/cgo3.go"}, 171 {"/progs/cgo4.go"}, 172 {"/progs/defer.go"}, 173 {"/progs/defer.out"}, 174 {"/progs/defer2.go"}, 175 {"/progs/defer2.out"}, 176 {"/progs/eff_bytesize.go"}, 177 {"/progs/eff_bytesize.out"}, 178 {"/progs/eff_qr.go"}, 179 {"/progs/eff_sequence.go"}, 180 {"/progs/eff_sequence.out"}, 181 {"/progs/eff_unused1.go"}, 182 {"/progs/eff_unused2.go"}, 183 {"/progs/error.go"}, 184 {"/progs/error2.go"}, 185 {"/progs/error3.go"}, 186 {"/progs/error4.go"}, 187 {"/progs/go1.go"}, 188 {"/progs/gobs1.go"}, 189 {"/progs/gobs2.go"}, 190 {"/progs/image_draw.go"}, 191 {"/progs/image_package1.go"}, 192 {"/progs/image_package1.out"}, 193 {"/progs/image_package2.go"}, 194 {"/progs/image_package2.out"}, 195 {"/progs/image_package3.go"}, 196 {"/progs/image_package3.out"}, 197 {"/progs/image_package4.go"}, 198 {"/progs/image_package4.out"}, 199 {"/progs/image_package5.go"}, 200 {"/progs/image_package5.out"}, 201 {"/progs/image_package6.go"}, 202 {"/progs/image_package6.out"}, 203 {"/progs/interface.go"}, 204 {"/progs/interface2.go"}, 205 {"/progs/interface2.out"}, 206 {"/progs/json1.go"}, 207 {"/progs/json2.go"}, 208 {"/progs/json2.out"}, 209 {"/progs/json3.go"}, 210 {"/progs/json4.go"}, 211 {"/progs/json5.go"}, 212 {"/progs/run"}, 213 {"/progs/slices.go"}, 214 {"/progs/timeout1.go"}, 215 {"/progs/timeout2.go"}, 216 {"/progs/update.bash"}, 217 } 218 219 for _, route := range static { 220 tree.addRoute(route.path, fakeHandler(route.path)) 221 } 222 ps := getParams() 223 224 b.ResetTimer() 225 for i := 0; i < b.N; i++ { 226 for _, request := range static { 227 tree.find(request.path, ps, false) 228 } 229 } 230 } 231 232 func BenchmarkTree_FindGithub(b *testing.B) { 233 tree := &router{method: "GET", root: &node{}, hasTsrHandler: make(map[string]bool)} 234 235 static := []*Route{ 236 // OAuth Authorizations 237 {"/authorizations"}, 238 {"/authorizations/:id"}, 239 //{"/authorizations"}, 240 //{"/authorizations/clients/:client_id"}, 241 //{"/authorizations/:id"}, 242 //{"/authorizations/:id"}, 243 {"/applications/:client_id/tokens/:access_token"}, 244 {"/applications/:client_id/tokens"}, 245 //{"/applications/:client_id/tokens/:access_token"}, 246 247 // Activity 248 {"/events"}, 249 {"/repos/:owner/:repo/events"}, 250 {"/networks/:owner/:repo/events"}, 251 {"/orgs/:org/events"}, 252 {"/users/:user/received_events"}, 253 {"/users/:user/received_events/public"}, 254 {"/users/:user/events"}, 255 {"/users/:user/events/public"}, 256 {"/users/:user/events/orgs/:org"}, 257 {"/feeds"}, 258 //{"/notifications"}, 259 {"/repos/:owner/:repo/notifications"}, 260 {"/notifications"}, 261 //{"/repos/:owner/:repo/notifications"}, 262 {"/notifications/threads/:id"}, 263 //{"/notifications/threads/:id"}, 264 {"/notifications/threads/:id/subscription"}, 265 //{"/notifications/threads/:id/subscription"}, 266 //{"/notifications/threads/:id/subscription"}, 267 {"/repos/:owner/:repo/stargazers"}, 268 {"/users/:user/starred"}, 269 {"/user/starred"}, 270 {"/user/starred/:owner/:repo"}, 271 //{"/user/starred/:owner/:repo"}, 272 //{"/user/starred/:owner/:repo"}, 273 {"/repos/:owner/:repo/subscribers"}, 274 {"/users/:user/subscriptions"}, 275 {"/user/subscriptions"}, 276 {"/repos/:owner/:repo/subscription"}, 277 //{"/repos/:owner/:repo/subscription"}, 278 //{"/repos/:owner/:repo/subscription"}, 279 {"/user/subscriptions/:owner/:repo"}, 280 //{"PUT", "/user/subscriptions/:owner/:repo"}, 281 //{"DELETE", "/user/subscriptions/:owner/:repo"}, 282 283 // Gists 284 {"/users/:user/gists"}, 285 {"/gists"}, 286 //{"GET", "/gists/public"}, 287 //{"GET", "/gists/starred"}, 288 {"/gists/:id"}, 289 //{"POST", "/gists"}, 290 //{"PATCH", "/gists/:id"}, 291 {"/gists/:id/star"}, 292 //{"DELETE", "/gists/:id/star"}, 293 //{"GET", "/gists/:id/star"}, 294 {"/gists/:id/forks"}, 295 //{"DELETE", "/gists/:id"}, 296 297 // Git Data 298 {"/repos/:owner/:repo/git/blobs/:sha"}, 299 {"/repos/:owner/:repo/git/blobs"}, 300 {"/repos/:owner/:repo/git/commits/:sha"}, 301 {"/repos/:owner/:repo/git/commits"}, 302 //{"GET", "/repos/:owner/:repo/git/refs/*ref"}, 303 {"/repos/:owner/:repo/git/refs"}, 304 //{"POST", "/repos/:owner/:repo/git/refs"}, 305 //{"PATCH", "/repos/:owner/:repo/git/refs/*ref"}, 306 //{"DELETE", "/repos/:owner/:repo/git/refs/*ref"}, 307 {"/repos/:owner/:repo/git/tags/:sha"}, 308 {"/repos/:owner/:repo/git/tags"}, 309 {"/repos/:owner/:repo/git/trees/:sha"}, 310 {"/repos/:owner/:repo/git/trees"}, 311 312 {"/issues"}, 313 {"/user/issues"}, 314 {"/orgs/:org/issues"}, 315 {"/repos/:owner/:repo/issues"}, 316 {"/repos/:owner/:repo/issues/:number"}, 317 //{"POST", "/repos/:owner/:repo/issues"}, 318 //{"PATCH", "/repos/:owner/:repo/issues/:number"}, 319 {"/repos/:owner/:repo/assignees"}, 320 {"/repos/:owner/:repo/assignees/:assignee"}, 321 {"/repos/:owner/:repo/issues/:number/comments"}, 322 //{"GET", "/repos/:owner/:repo/issues/comments"}, 323 //{"GET", "/repos/:owner/:repo/issues/comments/:id"}, 324 //{"POST", "/repos/:owner/:repo/issues/:number/comments"}, 325 //{"PATCH", "/repos/:owner/:repo/issues/comments/:id"}, 326 //{"DELETE", "/repos/:owner/:repo/issues/comments/:id"}, 327 {"/repos/:owner/:repo/issues/:number/events"}, 328 //{"GET", "/repos/:owner/:repo/issues/events"}, 329 //{"GET", "/repos/:owner/:repo/issues/events/:id"}, 330 {"/repos/:owner/:repo/labels"}, 331 {"/repos/:owner/:repo/labels/:name"}, 332 //{"POST", "/repos/:owner/:repo/labels"}, 333 //{"PATCH", "/repos/:owner/:repo/labels/:name"}, 334 //{"DELETE", "/repos/:owner/:repo/labels/:name"}, 335 {"/repos/:owner/:repo/issues/:number/labels"}, 336 //{"POST", "/repos/:owner/:repo/issues/:number/labels"}, 337 //{"DELETE", "/repos/:owner/:repo/issues/:number/labels/:name"}, 338 //{"PUT", "/repos/:owner/:repo/issues/:number/labels"}, 339 //{"DELETE", "/repos/:owner/:repo/issues/:number/labels"}, 340 {"/repos/:owner/:repo/milestones/:number/labels"}, 341 {"/repos/:owner/:repo/milestones"}, 342 {"/repos/:owner/:repo/milestones/:number"}, 343 //{"POST", "/repos/:owner/:repo/milestones"}, 344 //{"PATCH", "/repos/:owner/:repo/milestones/:number"}, 345 //{"DELETE", "/repos/:owner/:repo/milestones/:number"}, 346 347 // Miscellaneous 348 {"/emojis"}, 349 {"/gitignore/templates"}, 350 {"/gitignore/templates/:name"}, 351 {"/markdown"}, 352 {"/markdown/raw"}, 353 {"/meta"}, 354 {"/rate_limit"}, 355 356 // Organizations 357 {"/users/:user/orgs"}, 358 {"/user/orgs"}, 359 {"/orgs/:org"}, 360 //{"PATCH", "/orgs/:org"}, 361 {"/orgs/:org/members"}, 362 {"/orgs/:org/members/:user"}, 363 //{"DELETE", "/orgs/:org/members/:user"}, 364 {"/orgs/:org/public_members"}, 365 {"/orgs/:org/public_members/:user"}, 366 //{"PUT", "/orgs/:org/public_members/:user"}, 367 //{"DELETE", "/orgs/:org/public_members/:user"}, 368 {"/orgs/:org/teams"}, 369 {"/teams/:id"}, 370 //{"POST", "/orgs/:org/teams"}, 371 //{"PATCH", "/teams/:id"}, 372 //{"DELETE", "/teams/:id"}, 373 {"/teams/:id/members"}, 374 {"/teams/:id/members/:user"}, 375 //{"PUT", "/teams/:id/members/:user"}, 376 //{"DELETE", "/teams/:id/members/:user"}, 377 {"/teams/:id/repos"}, 378 {"/teams/:id/repos/:owner/:repo"}, 379 //{"PUT", "/teams/:id/repos/:owner/:repo"}, 380 //{"DELETE", "/teams/:id/repos/:owner/:repo"}, 381 {"/user/teams"}, 382 383 // Pull Requests 384 {"/repos/:owner/:repo/pulls"}, 385 {"/repos/:owner/:repo/pulls/:number"}, 386 //{"POST", "/repos/:owner/:repo/pulls"}, 387 //{"PATCH", "/repos/:owner/:repo/pulls/:number"}, 388 {"/repos/:owner/:repo/pulls/:number/commits"}, 389 {"/repos/:owner/:repo/pulls/:number/files"}, 390 {"/repos/:owner/:repo/pulls/:number/merge"}, 391 //{"PUT", "/repos/:owner/:repo/pulls/:number/merge"}, 392 {"/repos/:owner/:repo/pulls/:number/comments"}, 393 //{"GET", "/repos/:owner/:repo/pulls/comments"}, 394 //{"GET", "/repos/:owner/:repo/pulls/comments/:number"}, 395 //{"PUT", "/repos/:owner/:repo/pulls/:number/comments"}, 396 //{"PATCH", "/repos/:owner/:repo/pulls/comments/:number"}, 397 //{"DELETE", "/repos/:owner/:repo/pulls/comments/:number"}, 398 399 // Repositories 400 {"/user/repos"}, 401 {"/users/:user/repos"}, 402 {"/orgs/:org/repos"}, 403 {"/repositories"}, 404 //{"POST", "/user/repos"}, 405 //{"POST", "/orgs/:org/repos"}, 406 {"/repos/:owner/:repo"}, 407 //{"PATCH", "/repos/:owner/:repo"}, 408 {"/repos/:owner/:repo/contributors"}, 409 {"/repos/:owner/:repo/languages"}, 410 {"/repos/:owner/:repo/teams"}, 411 {"/repos/:owner/:repo/tags"}, 412 {"/repos/:owner/:repo/branches"}, 413 {"/repos/:owner/:repo/branches/:branch"}, 414 //{"DELETE", "/repos/:owner/:repo"}, 415 {"/repos/:owner/:repo/collaborators"}, 416 {"/repos/:owner/:repo/collaborators/:user"}, 417 //{"PUT", "/repos/:owner/:repo/collaborators/:user"}, 418 //{"DELETE", "/repos/:owner/:repo/collaborators/:user"}, 419 {"/repos/:owner/:repo/comments"}, 420 {"/repos/:owner/:repo/commits/:sha/comments"}, 421 //{"POST", "/repos/:owner/:repo/commits/:sha/comments"}, 422 {"/repos/:owner/:repo/comments/:id"}, 423 //{"PATCH", "/repos/:owner/:repo/comments/:id"}, 424 //{"DELETE", "/repos/:owner/:repo/comments/:id"}, 425 {"/repos/:owner/:repo/commits"}, 426 {"/repos/:owner/:repo/commits/:sha"}, 427 {"/repos/:owner/:repo/readme"}, 428 //{"GET", "/repos/:owner/:repo/contents/*path"}, 429 //{"PUT", "/repos/:owner/:repo/contents/*path"}, 430 //{"DELETE", "/repos/:owner/:repo/contents/*path"}, 431 //{"GET", "/repos/:owner/:repo/:archive_format/:ref"}, 432 {"/repos/:owner/:repo/keys"}, 433 {"/repos/:owner/:repo/keys/:id"}, 434 //{"POST", "/repos/:owner/:repo/keys"}, 435 //{"PATCH", "/repos/:owner/:repo/keys/:id"}, 436 //{"DELETE", "/repos/:owner/:repo/keys/:id"}, 437 {"/repos/:owner/:repo/downloads"}, 438 {"/repos/:owner/:repo/downloads/:id"}, 439 //{"DELETE", "/repos/:owner/:repo/downloads/:id"}, 440 {"/repos/:owner/:repo/forks"}, 441 //{"POST", "/repos/:owner/:repo/forks"}, 442 {"/repos/:owner/:repo/hooks"}, 443 {"/repos/:owner/:repo/hooks/:id"}, 444 //{"POST", "/repos/:owner/:repo/hooks"}, 445 //{"PATCH", "/repos/:owner/:repo/hooks/:id"}, 446 //{"POST", "/repos/:owner/:repo/hooks/:id/tests"}, 447 //{"DELETE", "/repos/:owner/:repo/hooks/:id"}, 448 //{"POST", "/repos/:owner/:repo/merges"}, 449 {"/repos/:owner/:repo/releases"}, 450 {"/repos/:owner/:repo/releases/:id"}, 451 //{"POST", "/repos/:owner/:repo/releases"}, 452 //{"PATCH", "/repos/:owner/:repo/releases/:id"}, 453 //{"DELETE", "/repos/:owner/:repo/releases/:id"}, 454 {"/repos/:owner/:repo/releases/:id/assets"}, 455 {"/repos/:owner/:repo/stats/contributors"}, 456 {"/repos/:owner/:repo/stats/commit_activity"}, 457 {"/repos/:owner/:repo/stats/code_frequency"}, 458 {"/repos/:owner/:repo/stats/participation"}, 459 {"/repos/:owner/:repo/stats/punch_card"}, 460 {"/repos/:owner/:repo/statuses/:ref"}, 461 //{"POST", "/repos/:owner/:repo/statuses/:ref"}, 462 463 // Search 464 {"/search/repositories"}, 465 {"/search/code"}, 466 {"/search/issues"}, 467 {"/search/users"}, 468 {"/legacy/issues/search/:owner/:repository/:state/:keyword"}, 469 {"/legacy/repos/search/:keyword"}, 470 {"/legacy/user/search/:keyword"}, 471 {"/legacy/user/email/:email"}, 472 473 // Users 474 {"/users/:user"}, 475 {"/user"}, 476 //{"PATCH", "/user"}, 477 {"/users"}, 478 {"/user/emails"}, 479 //{"POST", "/user/emails"}, 480 //{"DELETE", "/user/emails"}, 481 {"/users/:user/followers"}, 482 {"/user/followers"}, 483 {"/users/:user/following"}, 484 {"/user/following"}, 485 {"/user/following/:user"}, 486 {"/users/:user/following/:target_user"}, 487 //{"PUT", "/user/following/:user"}, 488 //{"DELETE", "/user/following/:user"}, 489 {"/users/:user/keys"}, 490 {"/user/keys"}, 491 {"/user/keys/:id"}, 492 //{"POST", "/user/keys"}, 493 //{"PATCH", "/user/keys/:id"}, 494 //{"DELETE", "/user/keys/:id"}, 495 } 496 497 for _, route := range static { 498 tree.addRoute(route.path, fakeHandler(route.path)) 499 } 500 ps := getParams() 501 502 b.ResetTimer() 503 for i := 0; i < b.N; i++ { 504 for _, request := range static { 505 tree.find(request.path, ps, false) 506 } 507 } 508 } 509 510 func BenchmarkTree_FindStaticTsr(b *testing.B) { 511 tree := &router{method: "GET", root: &node{}, hasTsrHandler: make(map[string]bool)} 512 513 routes := [...]string{ 514 "/doc/foo/go_faq.html/", 515 } 516 for _, route := range routes { 517 tree.addRoute(route, fakeHandler(route)) 518 } 519 tr := testRequests{ 520 {"/doc/foo/go_faq.html", false, "/doc/foo/go_faq.html", nil}, 521 } 522 ps := getParams() 523 524 b.ResetTimer() 525 for i := 0; i < b.N; i++ { 526 for _, request := range tr { 527 tree.find(request.path, ps, false) 528 } 529 } 530 } 531 532 func BenchmarkTree_FindParam(b *testing.B) { 533 tree := &router{method: "GET", root: &node{}, hasTsrHandler: make(map[string]bool)} 534 535 routes := [...]string{ 536 "/hi/:key1/foo/:key2", 537 } 538 for _, route := range routes { 539 tree.addRoute(route, fakeHandler(route)) 540 } 541 tr := testRequests{ 542 {"/hi/1/foo/2", false, "/hi", nil}, 543 } 544 ps := getParams() 545 546 b.ResetTimer() 547 for i := 0; i < b.N; i++ { 548 for _, request := range tr { 549 tree.find(request.path, ps, false) 550 } 551 } 552 } 553 554 func BenchmarkTree_FindParamTsr(b *testing.B) { 555 tree := &router{method: "GET", root: &node{}, hasTsrHandler: make(map[string]bool)} 556 557 routes := [...]string{ 558 "/hi/:key1/foo/:key2/", 559 } 560 for _, route := range routes { 561 tree.addRoute(route, fakeHandler(route)) 562 } 563 tr := testRequests{ 564 {"/hi/1/foo/2", false, "/hi", nil}, 565 } 566 ps := getParams() 567 568 b.ResetTimer() 569 for i := 0; i < b.N; i++ { 570 for _, request := range tr { 571 tree.find(request.path, ps, false) 572 } 573 } 574 } 575 576 func BenchmarkTree_FindAny(b *testing.B) { 577 tree := &router{method: "GET", root: &node{}, hasTsrHandler: make(map[string]bool)} 578 579 routes := [...]string{ 580 "/hi/*key1", 581 } 582 for _, route := range routes { 583 tree.addRoute(route, fakeHandler(route)) 584 } 585 tr := testRequests{ 586 {"/hi/foo", false, "/hi", nil}, 587 } 588 ps := getParams() 589 590 b.ResetTimer() 591 for i := 0; i < b.N; i++ { 592 for _, request := range tr { 593 tree.find(request.path, ps, false) 594 } 595 } 596 } 597 598 func BenchmarkTree_FindAnyFallback(b *testing.B) { 599 tree := &router{method: "GET", root: &node{}, hasTsrHandler: make(map[string]bool)} 600 601 routes := [...]string{ 602 "/hi/a/b/c/d/e/*key1", 603 "/*key2", 604 } 605 for _, route := range routes { 606 tree.addRoute(route, fakeHandler(route)) 607 } 608 tr := testRequests{ 609 {"/hi/a/b/c/d/f", false, "/*key2", nil}, 610 } 611 ps := getParams() 612 613 b.ResetTimer() 614 for i := 0; i < b.N; i++ { 615 for _, request := range tr { 616 tree.find(request.path, ps, false) 617 } 618 } 619 } 620 621 func BenchmarkRouteStatic(b *testing.B) { 622 r := NewEngine(config.NewOptions(nil)) 623 r.GET("/hi/foo", func(c context.Context, ctx *app.RequestContext) {}) 624 ctx := r.NewContext() 625 req := protocol.NewRequest("GET", "/hi/foo", nil) 626 req.CopyTo(&ctx.Request) 627 b.ResetTimer() 628 for i := 0; i < b.N; i++ { 629 r.ServeHTTP(context.Background(), ctx) 630 // ctx.index = -1 631 } 632 } 633 634 func BenchmarkRouteParam(b *testing.B) { 635 r := NewEngine(config.NewOptions(nil)) 636 r.GET("/hi/:user", func(c context.Context, ctx *app.RequestContext) {}) 637 ctx := r.NewContext() 638 req := protocol.NewRequest("GET", "/hi/foo", nil) 639 req.CopyTo(&ctx.Request) 640 b.ResetTimer() 641 for i := 0; i < b.N; i++ { 642 r.ServeHTTP(context.Background(), ctx) 643 // ctx.index = -1 644 } 645 } 646 647 func BenchmarkRouteAny(b *testing.B) { 648 r := NewEngine(config.NewOptions(nil)) 649 r.GET("/hi/*user", func(c context.Context, ctx *app.RequestContext) {}) 650 ctx := r.NewContext() 651 req := protocol.NewRequest("GET", "/hi/foo/dy", nil) 652 req.CopyTo(&ctx.Request) 653 b.ResetTimer() 654 for i := 0; i < b.N; i++ { 655 r.ServeHTTP(context.Background(), ctx) 656 // ctx.index = -1 657 } 658 }