-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(util/gconv): #3764 fix bool converting issue #3765
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2.修复bool转float测试错误 3.增加bool,int,uint,float的指针转换测试 3.对于转换到string,bool,float,int,uint等基础类型增加反射判断
wln32
changed the title
fix(util/gconv): 修复bool指针类型转换bug
fix(util/gconv): 修复bool指针类型转换bug #3764
Sep 9, 2024
gqcn
requested changes
Sep 10, 2024
gqcn
requested changes
Sep 10, 2024
gqcn
requested changes
Sep 10, 2024
gqcn
changed the title
fix(util/gconv): 修复bool指针类型转换bug #3764
fix(util/gconv): #3764 fix bool converting issue
Sep 10, 2024
intfunc reflectInt64(any interface{}) int64 {
if any == nil {
return 0
}
rv := reflect.ValueOf(any)
switch rv.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return int64(rv.Int())
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return int64(rv.Uint())
case reflect.Uintptr:
return int64(rv.Uint())
case reflect.Float32, reflect.Float64:
return int64(rv.Float())
case reflect.Bool:
if rv.Bool() {
return 1
}
return 0
case reflect.Ptr:
if rv.IsNil() {
return 0
}
if f, ok := any.(interface{ Int64() int64 }); ok {
return f.Int64()
}
// TODO: reflectInt64(rv.Elem()) 减少来回反射的开销
return reflectInt64(rv.Elem().Interface())
case reflect.Slice:
if rv.Type().Elem().Kind() == reflect.Uint8 {
return gbinary.DecodeToInt64(rv.Bytes())
}
case reflect.String:
var (
s = rv.String()
isMinus = false
)
if len(s) > 0 {
if s[0] == '-' {
isMinus = true
s = s[1:]
} else if s[0] == '+' {
s = s[1:]
}
}
// Hexadecimal
if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') {
if v, e := strconv.ParseInt(s[2:], 16, 64); e == nil {
if isMinus {
return -v
}
return v
}
}
// Decimal
if v, e := strconv.ParseInt(s, 10, 64); e == nil {
if isMinus {
return -v
}
return v
}
// Float64
if valueInt64, err := strconv.ParseFloat(s, 64); err != nil || math.IsNaN(valueInt64) {
return 0
} else {
return int64(valueInt64)
}
default:
}
if f, ok := any.(interface{ Int64() int64 }); ok {
return f.Int64()
}
return 0
}
intTests数据在单测文件里面util/gconv/gconv_z_unit_int_test.go
func Benchmark_Reflect_Int(b *testing.B) {
for range b.N {
for _, test := range intTests {
reflectInt64(test.value)
}
}
}
func Benchmark_TypeAssert_Int(b *testing.B) {
for range b.N {
for _, test := range intTests {
gconv.Int64(test.value)
}
}
}
go.exe test -benchmem -run='^$ -bench ^(Benchmark_Reflect_Int|Benchmark_TypeAssert_Int)$' 要测试的文件名
goos: windows
goarch: amd64
pkg: issue3764
cpu: AMD Ryzen 5 1400 Quad-Core Processor
Benchmark_Reflect_Int-8 397916 2826 ns/op 664 B/op 30 allocs/op
Benchmark_TypeAssert_Int-8 72208 15998 ns/op 2314 B/op 113 allocs/op
PASS
ok issue3764 2.885s uintfunc reflectUint64(any interface{}) uint64 {
if any == nil {
return 0
}
rv := reflect.ValueOf(any)
switch rv.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return uint64(rv.Int())
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return uint64(rv.Uint())
case reflect.Uintptr:
return uint64(rv.Uint())
case reflect.Float32, reflect.Float64:
return uint64(rv.Float())
case reflect.Bool:
if rv.Bool() {
return 1
}
return 0
case reflect.Ptr:
if rv.IsNil() {
return 0
}
switch f := any.(type) {
case (interface{ Int64() int64 }):
return uint64(f.Int64())
case (interface{ Uint64() uint64 }):
return f.Uint64()
case (interface{ Float64() float64 }):
return uint64(f.Float64())
}
// TODO: reflectUint64(rv.Elem()) 减少来回反射的开销
return reflectUint64(rv.Elem().Interface())
case reflect.Slice:
if rv.Type().Elem().Kind() == reflect.Uint8 {
return gbinary.DecodeToUint64(rv.Bytes())
}
case reflect.String:
var (
s = rv.String()
)
// Hexadecimal
if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') {
if v, e := strconv.ParseUint(s[2:], 16, 64); e == nil {
return v
}
}
// Decimal
if v, e := strconv.ParseUint(s, 10, 64); e == nil {
return v
}
// Float64
if valueFloat64 := gconv.Float64(any); math.IsNaN(valueFloat64) {
return 0
} else {
return uint64(valueFloat64)
}
default:
}
switch f := any.(type) {
case (interface{ Int64() int64 }):
return uint64(f.Int64())
case (interface{ Uint64() uint64 }):
return f.Uint64()
case (interface{ Float64() float64 }):
return uint64(f.Float64())
}
return 0
}
func Benchmark_Reflect_Uint(b *testing.B) {
for range b.N {
for _, test := range uintTests {
reflectUint64(test.value)
}
}
}
func Benchmark_TypeAssert_Uint(b *testing.B) {
for range b.N {
for _, test := range intTests {
gconv.Uint64(test.value)
}
}
}
go test -benchmem -run='^$ -bench ^(Benchmark_Reflect_Uint|Benchmark_TypeAssert_Uint)$' 要测试的文件名
goos: windows
goarch: amd64
pkg: issue3764
cpu: AMD Ryzen 5 1400 Quad-Core Processor
Benchmark_Reflect_Uint-8 541568 2247 ns/op 688 B/op 26 allocs/op
Benchmark_TypeAssert_Uint-8 81062 14867 ns/op 2514 B/op 112 allocs/op
PASS floatfunc Benchmark_Reflect_Float(b *testing.B) {
for range b.N {
for _, test := range floatTests {
reflectFloat64(test.value)
}
}
}
func Benchmark_TypeAssert_Float(b *testing.B) {
for range b.N {
for _, test := range floatTests {
gconv.Float64(test.value)
}
}
}
func reflectFloat64(any interface{}) float64 {
if any == nil {
return 0
}
rv := reflect.ValueOf(any)
switch rv.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return float64(rv.Int())
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return float64(rv.Uint())
case reflect.Uintptr:
return float64(rv.Uint())
case reflect.Float32, reflect.Float64:
return float64(rv.Float())
case reflect.Bool:
if rv.Bool() {
return 1
}
return 0
case reflect.Ptr:
if rv.IsNil() {
return 0
}
if f, ok := any.(interface{ Float64() float64 }); ok {
return float64(f.Float64())
}
// TODO: reflectFloat64(rv.Elem()) 减少来回反射的开销
return reflectFloat64(rv.Elem().Interface())
case reflect.Slice:
if rv.Type().Elem().Kind() == reflect.Uint8 {
return gbinary.DecodeToFloat64(rv.Bytes())
}
case reflect.String:
f, _ := strconv.ParseFloat(rv.String(), 64)
return f
default:
}
if f, ok := any.(interface{ Float64() float64 }); ok {
return f.Float64()
}
return 0
}
go.exe test -benchmem -run='^$ -bench ^(Benchmark_Reflect_Float|Benchmark_TypeAssert_Float)$' 被测试的文件名
goos: windows
goarch: amd64
pkg: issue3764
cpu: AMD Ryzen 5 1400 Quad-Core Processor
Benchmark_Reflect_Float-8 859450 1345 ns/op 280 B/op 12 allocs/op
Benchmark_TypeAssert_Float-8 116479 10000 ns/op 1249 B/op 67 allocs/op
PASS
ok issue3764 2.846s string的暂时没有,提升一般 |
2.对于(map,slice,array,struct)类型转换到bool标记TODO
* feat(database/gdb): add `time` field type for value converting for/from field (gogf#3712) * fix(net/goai): fix openapi miss `required` tag of `BizRequest` when set `CommonRequest` (gogf#3724) * perf(database/gdb): performance improvement for struct scanning when with feature disabled (gogf#3677) * up --------- Co-authored-by: CyJaySong <29367599+cyjaysong@users.noreply.github.com> Co-authored-by: Zwei <zwei.elen@outlook.com> Co-authored-by: wln32 <49137144+wln32@users.noreply.github.com>
2.增加各种基础类型指针强转nil的测试
Quality Gate passedIssues Measures |
gqcn
approved these changes
Sep 12, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
1.修复bool指针类型转换bug #3764
2.修复bool转float测试错误
3.增加bool,int,uint,float的指针转换测试
3.对于转换到string,bool,float,int,uint等基础类型增加反射判断