From cc74a8854a1a42919a9650cfe280d015d9374a1a Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Thu, 21 May 2020 21:00:33 +0800 Subject: [PATCH 1/3] chore: improve snakeCasedName performance --- names/mapper.go | 21 +++++++++++++++++++++ names/mapper_test.go | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/names/mapper.go b/names/mapper.go index 4aaf0844..b720479e 100644 --- a/names/mapper.go +++ b/names/mapper.go @@ -7,6 +7,7 @@ package names import ( "strings" "sync" + "unsafe" ) // Mapper represents a name convertation between struct's fields name and table's column name @@ -92,6 +93,26 @@ func snakeCasedName(name string) string { return string(newstr) } +func b2s(b []byte) string { + return *(*string)(unsafe.Pointer(&b)) +} + +func snakeCasedNameNew(name string) string { + newstr := make([]byte, 0) + for i := 0; i < len(name); i++ { + c := name[i] + if isUpper := 'A' <= c && c <= 'Z'; isUpper { + if i > 0 { + newstr = append(newstr, '_') + } + c += 'a' - 'A' + } + newstr = append(newstr, c) + } + + return b2s(newstr) +} + func (mapper SnakeMapper) Obj2Table(name string) string { return snakeCasedName(name) } diff --git a/names/mapper_test.go b/names/mapper_test.go index 0edfd2a8..6945b84c 100644 --- a/names/mapper_test.go +++ b/names/mapper_test.go @@ -5,6 +5,7 @@ package names import ( + "strings" "testing" ) @@ -47,3 +48,23 @@ 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) + } +} + +func BenchmarkSnakeCasedNameNew(b *testing.B) { + b.ReportAllocs() + b.ResetTimer() + + s := strings.Repeat("FooBar", 32) + for i := 0; i < b.N; i++ { + _ = snakeCasedNameNew(s) + } +} -- 2.40.1 From fdb676564810b3b293d258d4ac5ce7caebc966a9 Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Thu, 21 May 2020 22:15:57 +0800 Subject: [PATCH 2/3] chore: udpate --- names/mapper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/names/mapper.go b/names/mapper.go index b720479e..e7561a83 100644 --- a/names/mapper.go +++ b/names/mapper.go @@ -98,7 +98,7 @@ func b2s(b []byte) string { } func snakeCasedNameNew(name string) string { - newstr := make([]byte, 0) + newstr := make([]byte, 0, len(name)) for i := 0; i < len(name); i++ { c := name[i] if isUpper := 'A' <= c && c <= 'Z'; isUpper { -- 2.40.1 From 99f0e5e05c3b074f8db5b1bc269dadc73b4c07cd Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Thu, 21 May 2020 22:29:44 +0800 Subject: [PATCH 3/3] chore: update --- names/mapper.go | 19 ++----------------- names/mapper_test.go | 10 ---------- 2 files changed, 2 insertions(+), 27 deletions(-) diff --git a/names/mapper.go b/names/mapper.go index e7561a83..80aa48d5 100644 --- a/names/mapper.go +++ b/names/mapper.go @@ -78,27 +78,12 @@ func (m SameMapper) Table2Obj(t string) string { type SnakeMapper struct { } -func snakeCasedName(name string) string { - newstr := make([]rune, 0) - for idx, chr := range name { - if isUpper := 'A' <= chr && chr <= 'Z'; isUpper { - if idx > 0 { - newstr = append(newstr, '_') - } - chr -= ('A' - 'a') - } - newstr = append(newstr, chr) - } - - return string(newstr) -} - func b2s(b []byte) string { return *(*string)(unsafe.Pointer(&b)) } -func snakeCasedNameNew(name string) string { - newstr := make([]byte, 0, len(name)) +func snakeCasedName(name string) string { + newstr := make([]byte, 0, len(name)+1) for i := 0; i < len(name); i++ { c := name[i] if isUpper := 'A' <= c && c <= 'Z'; isUpper { diff --git a/names/mapper_test.go b/names/mapper_test.go index 6945b84c..5c6dc5d9 100644 --- a/names/mapper_test.go +++ b/names/mapper_test.go @@ -58,13 +58,3 @@ func BenchmarkSnakeCasedName(b *testing.B) { _ = snakeCasedName(s) } } - -func BenchmarkSnakeCasedNameNew(b *testing.B) { - b.ReportAllocs() - b.ResetTimer() - - s := strings.Repeat("FooBar", 32) - for i := 0; i < b.N; i++ { - _ = snakeCasedNameNew(s) - } -} -- 2.40.1