Fix github uri bench, update comments and benchmark results

This commit is contained in:
Sky Johnson 2024-08-23 22:15:58 -05:00
parent 801ef570e2
commit 5d8a722be6
4 changed files with 57 additions and 26 deletions

View File

@ -42,15 +42,17 @@ data := router.LookupNoAlloc("GET", "/users/42", func(key string, value string)
## Benchmarks
```
goos: linux
goarch: amd64
pkg: git.sharkk.net/Go/Router/tests
cpu: AMD Ryzen 9 7950X 16-Core Processor
BenchmarkBlog/Len1-Param0-32 384992013 3.337 ns/op 0 B/op 0 allocs/op
BenchmarkBlog/Len1-Param1-32 199599014 6.021 ns/op 0 B/op 0 allocs/op
BenchmarkGithub/Len7-Param0-32 256332994 4.678 ns/op 0 B/op 0 allocs/op
BenchmarkGithub/Len7-Param1-32 269038417 4.455 ns/op 0 B/op 0 allocs/op
BenchmarkGithub/Len7-Param2-32 256228226 4.673 ns/op 0 B/op 0 allocs/op
PASS
ok git.sharkk.net/Go/Router/tests 8.410s
cpu: AMD Ryzen 9 7950X 16-Core Processor
BenchmarkBlog/Len1-Params0-32 268391120 4.461 ns/op 0 B/op 0 allocs/op
BenchmarkBlog/Len1-Params0-NoAlloc-32 383737024 3.123 ns/op 0 B/op 0 allocs/op
BenchmarkBlog/Len1-Param1-32 23690427 47.85 ns/op 32 B/op 1 allocs/op
BenchmarkBlog/Len1-Param1-NoAlloc-32 248275540 4.913 ns/op 0 B/op 0 allocs/op
BenchmarkGithub/Len7-Params0-32 148926122 8.043 ns/op 0 B/op 0 allocs/op
BenchmarkGithub/Len7-Params0-NoAlloc-32 168011829 7.153 ns/op 0 B/op 0 allocs/op
BenchmarkGithub/Len7-Params1-32 22188592 47.25 ns/op 32 B/op 1 allocs/op
BenchmarkGithub/Len7-Params1-NoAlloc-32 100000000 11.29 ns/op 0 B/op 0 allocs/op
BenchmarkGithub/Len7-Params3-32 10181496 111.3 ns/op 96 B/op 2 allocs/op
BenchmarkGithub/Len7-Params3-NoAlloc-32 46369563 25.54 ns/op 0 B/op 0 allocs/op
```

View File

@ -1,6 +1,5 @@
package router
// Router is a high-performance router.
type Router[T any] struct {
get Tree[T]
post Tree[T]
@ -13,18 +12,18 @@ type Router[T any] struct {
options Tree[T]
}
// New creates a new router containing trees for every HTTP method.
// Creates a new router containing trees for every HTTP method.
func New[T any]() *Router[T] {
return &Router[T]{}
}
// Add registers a new handler for the given method and path.
// Registers a new handler for the given method and path.
func (router *Router[T]) Add(method string, path string, handler T) {
tree := router.selectTree(method)
tree.Add(path, handler)
}
// Lookup finds the handler and parameters for the given route.
// Finds the handler and parameters for the given route.
func (router *Router[T]) Lookup(method string, path string) (T, []Parameter) {
if method[0] == 'G' {
return router.get.Lookup(path)
@ -34,7 +33,7 @@ func (router *Router[T]) Lookup(method string, path string) (T, []Parameter) {
return tree.Lookup(path)
}
// LookupNoAlloc finds the handler and parameters for the given route without using any memory allocations.
// Finds the handler and parameters for the given route without using any memory allocations.
func (router *Router[T]) LookupNoAlloc(method string, path string, addParameter func(string, string)) T {
if method[0] == 'G' {
return router.get.LookupNoAlloc(path, addParameter)
@ -44,7 +43,7 @@ func (router *Router[T]) LookupNoAlloc(method string, path string, addParameter
return tree.LookupNoAlloc(path, addParameter)
}
// Map traverses all trees and calls the given function on every node.
// Traverses all trees and calls the given function on every node.
func (router *Router[T]) Map(transform func(T) T) {
router.get.Map(transform)
router.post.Map(transform)
@ -57,7 +56,7 @@ func (router *Router[T]) Map(transform func(T) T) {
router.options.Map(transform)
}
// selectTree returns the tree by the given HTTP method.
// Returns the tree by the given HTTP method.
func (router *Router[T]) selectTree(method string) *Tree[T] {
switch method {
case "GET":

View File

@ -89,7 +89,7 @@ func (tree *Tree[T]) Lookup(path string) (T, []Parameter) {
return data, params
}
// LookupNoAlloc finds the data for the given path without using any memory allocations.
// Finds the data for the given path without using any memory allocations.
func (tree *Tree[T]) LookupNoAlloc(path string, addParameter func(key string, value string)) T {
var (
i uint

View File

@ -17,13 +17,25 @@ func BenchmarkBlog(b *testing.B) {
r.Add(route.Method, route.Path, "")
}
b.Run("Len1-Param0", func(b *testing.B) {
b.Run("Len1-Params0", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r.Lookup("GET", "/")
}
})
b.Run("Len1-Params0-NoAlloc", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r.LookupNoAlloc("GET", "/", noop)
}
})
b.Run("Len1-Param1", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r.Lookup("GET", "/:id")
}
})
b.Run("Len1-Param1-NoAlloc", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r.LookupNoAlloc("GET", "/:id", noop)
}
@ -31,26 +43,44 @@ func BenchmarkBlog(b *testing.B) {
}
func BenchmarkGithub(b *testing.B) {
routes := routes("routes.txt")
routes := routes("github.txt")
r := router.New[string]()
for _, route := range routes {
r.Add(route.Method, route.Path, "")
}
b.Run("Len7-Param0", func(b *testing.B) {
b.Run("Len7-Params0", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r.Lookup("GET", "/issues")
}
})
b.Run("Len7-Params0-NoAlloc", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r.LookupNoAlloc("GET", "/issues", noop)
}
})
b.Run("Len7-Param1", func(b *testing.B) {
b.Run("Len7-Params1", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r.Lookup("GET", "/gists/:id")
}
})
b.Run("Len7-Params1-NoAlloc", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r.LookupNoAlloc("GET", "/gists/:id", noop)
}
})
b.Run("Len7-Param2", func(b *testing.B) {
b.Run("Len7-Params3", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r.Lookup("GET", "/repos/:owner/:repo/issues")
}
})
b.Run("Len7-Params3-NoAlloc", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r.LookupNoAlloc("GET", "/repos/:owner/:repo/issues", noop)
}
@ -63,7 +93,7 @@ type Route struct {
Path string
}
// Routes loads all routes from a text file.
// Loads all routes from a text file.
func routes(fileName string) []Route {
var routes []Route
@ -79,7 +109,7 @@ func routes(fileName string) []Route {
return routes
}
// Lines is a utility function to easily read every line in a text file.
// Easily read every line in a text file.
func lines(fileName string) <-chan string {
lines := make(chan string)