From 5d8a722be6206c291342ff5f541d03919ddd9179 Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Fri, 23 Aug 2024 22:15:58 -0500 Subject: [PATCH] Fix github uri bench, update comments and benchmark results --- README.md | 24 +++++++++++----------- Router.go | 13 ++++++------ Tree.go | 2 +- tests/benchmark_test.go | 44 ++++++++++++++++++++++++++++++++++------- 4 files changed, 57 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index a5f075e..29b3b58 100644 --- a/README.md +++ b/README.md @@ -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 ``` \ No newline at end of file diff --git a/Router.go b/Router.go index 3db0647..6e2b8c4 100644 --- a/Router.go +++ b/Router.go @@ -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": diff --git a/Tree.go b/Tree.go index 5bcd10b..bd1d438 100644 --- a/Tree.go +++ b/Tree.go @@ -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 diff --git a/tests/benchmark_test.go b/tests/benchmark_test.go index 004da16..fa22e7f 100644 --- a/tests/benchmark_test.go +++ b/tests/benchmark_test.go @@ -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)