chore: improve countParams performance

This commit is contained in:
Bo-Yi Wu 2020-05-17 15:24:08 +08:00
parent e3336ad2f5
commit 8467ce7abc
2 changed files with 39 additions and 10 deletions

35
tree.go
View File

@ -5,13 +5,20 @@
package gin package gin
import ( import (
"bytes"
"net/url" "net/url"
"reflect"
"strings" "strings"
"unicode" "unicode"
"unicode/utf8" "unicode/utf8"
"unsafe" "unsafe"
) )
var (
strColon = []byte(":")
strStar = []byte("*")
)
// Param is a single URL parameter, consisting of a key and a value. // Param is a single URL parameter, consisting of a key and a value.
type Param struct { type Param struct {
Key string Key string
@ -41,10 +48,6 @@ func (ps Params) ByName(name string) (va string) {
return return
} }
func bytesToStr(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
type methodTree struct { type methodTree struct {
method string method string
root *node root *node
@ -77,14 +80,26 @@ func longestCommonPrefix(a, b string) int {
return i return i
} }
func bytesToStr(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
func strToBytes(s string) (b []byte) {
/* #nosec G103 */
bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
/* #nosec G103 */
sh := *(*reflect.StringHeader)(unsafe.Pointer(&s))
bh.Data = sh.Data
bh.Len = sh.Len
bh.Cap = sh.Len
return b
}
func countParams(path string) uint16 { func countParams(path string) uint16 {
var n uint var n uint
for i := range []byte(path) { s := strToBytes(path)
switch path[i] { n += uint(bytes.Count(s, strColon))
case ':', '*': n += uint(bytes.Count(s, strStar))
n++
}
}
return uint16(n) return uint16(n)
} }

View File

@ -93,6 +93,20 @@ func TestCountParams(t *testing.T) {
} }
} }
var s = strings.Repeat("/:param", 5)
func BenchmarkCountParamsOld(b *testing.B) {
for i := 0; i < b.N; i++ {
countParamsOld(s)
}
}
func BenchmarkCountParams(b *testing.B) {
for i := 0; i < b.N; i++ {
countParamsNew(s)
}
}
func TestTreeAddAndGet(t *testing.T) { func TestTreeAddAndGet(t *testing.T) {
tree := &node{} tree := &node{}