chore: improve snakeCasedName performance #1688

Merged
lunny merged 3 commits from performance into master 2020-05-22 02:54:50 +00:00
2 changed files with 24 additions and 7 deletions

View File

@ -7,6 +7,7 @@ package names
import ( import (
"strings" "strings"
"sync" "sync"
"unsafe"
) )
// Mapper represents a name convertation between struct's fields name and table's column name // Mapper represents a name convertation between struct's fields name and table's column name
@ -77,19 +78,24 @@ func (m SameMapper) Table2Obj(t string) string {
type SnakeMapper struct { type SnakeMapper struct {
} }
func b2s(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
func snakeCasedName(name string) string { func snakeCasedName(name string) string {
newstr := make([]rune, 0) newstr := make([]byte, 0, len(name)+1)
for idx, chr := range name { for i := 0; i < len(name); i++ {
if isUpper := 'A' <= chr && chr <= 'Z'; isUpper { c := name[i]
if idx > 0 { if isUpper := 'A' <= c && c <= 'Z'; isUpper {
if i > 0 {
newstr = append(newstr, '_') newstr = append(newstr, '_')
} }
chr -= ('A' - 'a') c += 'a' - 'A'
} }
newstr = append(newstr, chr) newstr = append(newstr, c)
} }
return string(newstr) return b2s(newstr)
} }
func (mapper SnakeMapper) Obj2Table(name string) string { func (mapper SnakeMapper) Obj2Table(name string) string {
Outdated
Review

How about give a length ? make([]byte, 0, len(name))

How about give a length ? `make([]byte, 0, len(name)) `

Done.

goos: darwin
goarch: amd64
pkg: xorm.io/xorm/names
BenchmarkSnakeCasedName-8         313640              3524 ns/op            2328 B/op          9 allocs/op
BenchmarkSnakeCasedNameNew-8     1901515               617 ns/op             576 B/op          2 allocs/op
PASS
ok      xorm.io/xorm/names      2.976s
Done. ``` goos: darwin goarch: amd64 pkg: xorm.io/xorm/names BenchmarkSnakeCasedName-8 313640 3524 ns/op 2328 B/op 9 allocs/op BenchmarkSnakeCasedNameNew-8 1901515 617 ns/op 576 B/op 2 allocs/op PASS ok xorm.io/xorm/names 2.976s ```
Outdated
Review

Sorry, maybe newstr := make([]byte, 0, len(name)+1 is better.

Sorry, maybe `newstr := make([]byte, 0, len(name)+1` is better.
Review

Done

Done

View File

@ -5,6 +5,7 @@
package names package names
import ( import (
"strings"
"testing" "testing"
) )
@ -47,3 +48,13 @@ func TestGonicMapperToObj(t *testing.T) {
} }
} }
} }
func BenchmarkSnakeCasedName(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
s := strings.Repeat("FooBar", 32)
for i := 0; i < b.N; i++ {
_ = snakeCasedName(s)
}
}