Skip to content

Commit 1b4ebc0

Browse files
authored
perf(util/gconv): add cache logic to enhance performance (#3673)
1 parent 803cb5a commit 1b4ebc0

22 files changed

+998
-358
lines changed

util/gconv/gconv.go

+22-11
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
// Package gconv implements powerful and convenient converting functionality for any types of variables.
88
//
9-
// This package should keep much less dependencies with other packages.
9+
// This package should keep much fewer dependencies with other packages.
1010
package gconv
1111

1212
import (
@@ -23,7 +23,8 @@ import (
2323
"github.com/gogf/gf/v2/internal/json"
2424
"github.com/gogf/gf/v2/internal/reflection"
2525
"github.com/gogf/gf/v2/os/gtime"
26-
"github.com/gogf/gf/v2/util/gtag"
26+
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
27+
"github.com/gogf/gf/v2/util/gconv/internal/structcache"
2728
)
2829

2930
var (
@@ -35,13 +36,23 @@ var (
3536
"off": {},
3637
"false": {},
3738
}
38-
39-
// StructTagPriority defines the default priority tags for Map*/Struct* functions.
40-
// Note that, the `gconv/param` tags are used by old version of package.
41-
// It is strongly recommended using short tag `c/p` instead in the future.
42-
StructTagPriority = gtag.StructTagPriority
4339
)
4440

41+
func init() {
42+
// register common converters for internal usage.
43+
structcache.RegisterCommonConverter(structcache.CommonConverter{
44+
Int64: Int64,
45+
Uint64: Uint64,
46+
String: String,
47+
Float32: Float32,
48+
Float64: Float64,
49+
Time: Time,
50+
GTime: GTime,
51+
Bytes: Bytes,
52+
Bool: Bool,
53+
})
54+
}
55+
4556
// Byte converts `any` to byte.
4657
func Byte(any interface{}) byte {
4758
if v, ok := any.(byte); ok {
@@ -63,7 +74,7 @@ func Bytes(any interface{}) []byte {
6374
return value
6475

6576
default:
66-
if f, ok := value.(iBytes); ok {
77+
if f, ok := value.(localinterface.IBytes); ok {
6778
return f.Bytes()
6879
}
6980
originValueAndKind := reflection.OriginValueAndKind(any)
@@ -174,12 +185,12 @@ func String(any interface{}) string {
174185
if value == nil {
175186
return ""
176187
}
177-
if f, ok := value.(iString); ok {
188+
if f, ok := value.(localinterface.IString); ok {
178189
// If the variable implements the String() interface,
179190
// then use that interface to perform the conversion
180191
return f.String()
181192
}
182-
if f, ok := value.(iError); ok {
193+
if f, ok := value.(localinterface.IError); ok {
183194
// If the variable implements the Error() interface,
184195
// then use that interface to perform the conversion
185196
return f.Error()
@@ -235,7 +246,7 @@ func Bool(any interface{}) bool {
235246
}
236247
return true
237248
default:
238-
if f, ok := value.(iBool); ok {
249+
if f, ok := value.(localinterface.IBool); ok {
239250
return f.Bool()
240251
}
241252
rv := reflect.ValueOf(any)

util/gconv/gconv_converter.go

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/gogf/gf/v2/errors/gcode"
1313
"github.com/gogf/gf/v2/errors/gerror"
14+
"github.com/gogf/gf/v2/util/gconv/internal/structcache"
1415
)
1516

1617
type (
@@ -82,6 +83,7 @@ func RegisterConverter(fn interface{}) (err error) {
8283
return
8384
}
8485
registeredOutTypeMap[outType] = reflect.ValueOf(fn)
86+
structcache.RegisterCustomConvertType(outType)
8587
return
8688
}
8789

util/gconv/gconv_float.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"strconv"
1111

1212
"github.com/gogf/gf/v2/encoding/gbinary"
13+
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
1314
)
1415

1516
// Float32 converts `any` to float32.
@@ -25,7 +26,7 @@ func Float32(any interface{}) float32 {
2526
case []byte:
2627
return gbinary.DecodeToFloat32(value)
2728
default:
28-
if f, ok := value.(iFloat32); ok {
29+
if f, ok := value.(localinterface.IFloat32); ok {
2930
return f.Float32()
3031
}
3132
v, _ := strconv.ParseFloat(String(any), 64)
@@ -46,7 +47,7 @@ func Float64(any interface{}) float64 {
4647
case []byte:
4748
return gbinary.DecodeToFloat64(value)
4849
default:
49-
if f, ok := value.(iFloat64); ok {
50+
if f, ok := value.(localinterface.IFloat64); ok {
5051
return f.Float64()
5152
}
5253
v, _ := strconv.ParseFloat(String(any), 64)

util/gconv/gconv_int.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"strconv"
1212

1313
"github.com/gogf/gf/v2/encoding/gbinary"
14+
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
1415
)
1516

1617
// Int converts `any` to int.
@@ -95,7 +96,7 @@ func Int64(any interface{}) int64 {
9596
case []byte:
9697
return gbinary.DecodeToInt64(value)
9798
default:
98-
if f, ok := value.(iInt64); ok {
99+
if f, ok := value.(localinterface.IInt64); ok {
99100
return f.Int64()
100101
}
101102
var (

util/gconv/gconv_interface.go

-117
This file was deleted.

util/gconv/gconv_map.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/gogf/gf/v2/internal/empty"
1414
"github.com/gogf/gf/v2/internal/json"
1515
"github.com/gogf/gf/v2/internal/utils"
16+
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
1617
"github.com/gogf/gf/v2/util/gtag"
1718
)
1819

@@ -40,8 +41,8 @@ type MapOption struct {
4041
// Map converts any variable `value` to map[string]interface{}. If the parameter `value` is not a
4142
// map/struct/*struct type, then the conversion will fail and returns nil.
4243
//
43-
// If `value` is a struct/*struct object, the second parameter `tags` specifies the most priority
44-
// tags that will be detected, otherwise it detects the tags in order of:
44+
// If `value` is a struct/*struct object, the second parameter `priorityTagAndFieldName` specifies the most priority
45+
// priorityTagAndFieldName that will be detected, otherwise it detects the priorityTagAndFieldName in order of:
4546
// gconv, json, field name.
4647
func Map(value interface{}, option ...MapOption) map[string]interface{} {
4748
return doMapConvert(value, recursiveTypeAuto, false, option...)
@@ -67,10 +68,9 @@ func doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool
6768
return nil
6869
}
6970
// It redirects to its underlying value if it has implemented interface iVal.
70-
if v, ok := value.(iVal); ok {
71+
if v, ok := value.(localinterface.IVal); ok {
7172
value = v.Val()
7273
}
73-
7474
var (
7575
usedOption = getUsedMapOption(option...)
7676
newTags = gtag.StructTagPriority
@@ -334,7 +334,7 @@ func doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) in
334334
case reflect.Struct:
335335
var dataMap = make(map[string]interface{})
336336
// Map converting interface check.
337-
if v, ok := in.Value.(iMapStrAny); ok {
337+
if v, ok := in.Value.(localinterface.IMapStrAny); ok {
338338
// Value copy, in case of concurrent safety.
339339
for mapK, mapV := range v.MapStrAny() {
340340
if in.RecursiveOption {

util/gconv/gconv_scan.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/gogf/gf/v2/errors/gcode"
1313
"github.com/gogf/gf/v2/errors/gerror"
1414
"github.com/gogf/gf/v2/internal/json"
15+
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
1516
)
1617

1718
// Scan automatically checks the type of `pointer` and converts `params` to `pointer`.
@@ -197,7 +198,7 @@ func doConvertWithJsonCheck(srcValue interface{}, dstPointer interface{}) (ok bo
197198

198199
default:
199200
// The `params` might be struct that implements interface function Interface, eg: gvar.Var.
200-
if v, ok := srcValue.(iInterface); ok {
201+
if v, ok := srcValue.(localinterface.IInterface); ok {
201202
return doConvertWithJsonCheck(v.Interface(), dstPointer)
202203
}
203204
}

util/gconv/gconv_slice_any.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/gogf/gf/v2/internal/json"
1313
"github.com/gogf/gf/v2/internal/reflection"
14+
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
1415
)
1516

1617
// SliceAny is alias of Interfaces.
@@ -104,7 +105,7 @@ func Interfaces(any interface{}) []interface{} {
104105
if array != nil {
105106
return array
106107
}
107-
if v, ok := any.(iInterfaces); ok {
108+
if v, ok := any.(localinterface.IInterfaces); ok {
108109
return v.Interfaces()
109110
}
110111
// JSON format string value converting.

util/gconv/gconv_slice_float.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/gogf/gf/v2/internal/json"
1313
"github.com/gogf/gf/v2/internal/reflection"
14+
"github.com/gogf/gf/v2/util/gconv/internal/localinterface"
1415
)
1516

1617
// SliceFloat is alias of Floats.
@@ -126,10 +127,10 @@ func Float32s(any interface{}) []float32 {
126127
if array != nil {
127128
return array
128129
}
129-
if v, ok := any.(iFloats); ok {
130+
if v, ok := any.(localinterface.IFloats); ok {
130131
return Float32s(v.Floats())
131132
}
132-
if v, ok := any.(iInterfaces); ok {
133+
if v, ok := any.(localinterface.IInterfaces); ok {
133134
return Float32s(v.Interfaces())
134135
}
135136
// JSON format string value converting.
@@ -250,10 +251,10 @@ func Float64s(any interface{}) []float64 {
250251
if array != nil {
251252
return array
252253
}
253-
if v, ok := any.(iFloats); ok {
254+
if v, ok := any.(localinterface.IFloats); ok {
254255
return v.Floats()
255256
}
256-
if v, ok := any.(iInterfaces); ok {
257+
if v, ok := any.(localinterface.IInterfaces); ok {
257258
return Floats(v.Interfaces())
258259
}
259260
// JSON format string value converting.

0 commit comments

Comments
 (0)