Improved performance

This commit is contained in:
Eduard Urbach 2024-03-15 09:52:34 +01:00
parent 8f507e4430
commit 7ec90a691b
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
2 changed files with 22 additions and 23 deletions

View File

@ -59,11 +59,11 @@ coverage: 100.0% of statements
## Benchmarks
```
BenchmarkBlog/Len1-Param0-12 201446469 5.956 ns/op 0 B/op 0 allocs/op
BenchmarkBlog/Len1-Param1-12 130212613 9.221 ns/op 0 B/op 0 allocs/op
BenchmarkGitHub/Len7-Param0-12 70604431 16.97 ns/op 0 B/op 0 allocs/op
BenchmarkGitHub/Len7-Param1-12 50499285 22.55 ns/op 0 B/op 0 allocs/op
BenchmarkGitHub/Len7-Param2-12 25460875 46.84 ns/op 0 B/op 0 allocs/op
BenchmarkBlog/Len1-Param0-12 211814850 5.646 ns/op 0 B/op 0 allocs/op
BenchmarkBlog/Len1-Param1-12 132838722 8.978 ns/op 0 B/op 0 allocs/op
BenchmarkGitHub/Len7-Param0-12 84768382 14.14 ns/op 0 B/op 0 allocs/op
BenchmarkGitHub/Len7-Param1-12 55290044 20.74 ns/op 0 B/op 0 allocs/op
BenchmarkGitHub/Len7-Param2-12 26057244 46.08 ns/op 0 B/op 0 allocs/op
```
## License

35
Tree.go
View File

@ -92,11 +92,10 @@ func (tree *Tree[T]) Lookup(path string) (T, []Parameter) {
// LookupNoAlloc 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
offset uint
wildcardOffset uint
wildcard *treeNode[T]
node = &tree.root
i uint
wildcardPath string
wildcard *treeNode[T]
node = &tree.root
)
// Skip the first loop iteration if the starting characters are equal
@ -110,10 +109,10 @@ begin:
// The node we just checked is entirely included in our path.
// node: /|
// path: /|blog
if i-offset == uint(len(node.prefix)) {
if i == uint(len(node.prefix)) {
if node.wildcard != nil {
wildcard = node.wildcard
wildcardOffset = i
wildcardPath = path[i:]
}
char := path[i]
@ -123,8 +122,8 @@ begin:
if index != 0 {
node = node.children[index]
offset = i
i++
path = path[i:]
i = 1
continue
}
}
@ -133,25 +132,25 @@ begin:
// path: /|blog
if node.parameter != nil {
node = node.parameter
offset = i
i++
path = path[i:]
i = 1
for i < uint(len(path)) {
// node: /:id|/posts
// path: /123|/posts
if path[i] == separator {
addParameter(node.prefix, path[offset:i])
addParameter(node.prefix, path[:i])
index := node.indices[separator-node.startIndex]
node = node.children[index]
offset = i
i++
path = path[i:]
i = 1
goto begin
}
i++
}
addParameter(node.prefix, path[offset:i])
addParameter(node.prefix, path[:i])
return node.data
}
@ -163,7 +162,7 @@ begin:
// We got a conflict.
// node: /b|ag
// path: /b|riefcase
if path[i] != node.prefix[i-offset] {
if path[i] != node.prefix[i] {
goto notFound
}
@ -172,7 +171,7 @@ begin:
// node: /blog|
// path: /blog|
if i-offset == uint(len(node.prefix)) {
if i == uint(len(node.prefix)) {
return node.data
}
@ -180,7 +179,7 @@ begin:
// path: /|image.png
notFound:
if wildcard != nil {
addParameter(wildcard.prefix, path[wildcardOffset:])
addParameter(wildcard.prefix, wildcardPath)
return wildcard.data
}