gain another 5% on average by changing tag type from bool's to enum

```

benchmark                                               old ns/op     new ns/op     delta
BenchmarkFieldSuccess-4                                 117           116           -0.85%
BenchmarkFieldFailure-4                                 675           651           -3.56%
BenchmarkFieldDiveSuccess-4                             2518          2418          -3.97%
BenchmarkFieldDiveFailure-4                             3096          3011          -2.75%
BenchmarkFieldCustomTypeSuccess-4                       319           297           -6.90%
BenchmarkFieldCustomTypeFailure-4                       688           680           -1.16%
BenchmarkFieldOrTagSuccess-4                            1251          1176          -6.00%
BenchmarkFieldOrTagFailure-4                            1090          1073          -1.56%
BenchmarkStructLevelValidationSuccess-4                 558           567           +1.61%
BenchmarkStructLevelValidationFailure-4                 608           562           -7.57%
BenchmarkStructSimpleCustomTypeSuccess-4                702           636           -9.40%
BenchmarkStructSimpleCustomTypeFailure-4                1380          1295          -6.16%
BenchmarkStructPartialSuccess-4                         1139          1058          -7.11%
BenchmarkStructPartialFailure-4                         1760          1648          -6.36%
BenchmarkStructExceptSuccess-4                          951           917           -3.58%
BenchmarkStructExceptFailure-4                          1147          1085          -5.41%
BenchmarkStructSimpleCrossFieldSuccess-4                873           783           -10.31%
BenchmarkStructSimpleCrossFieldFailure-4                1478          1384          -6.36%
BenchmarkStructSimpleCrossStructCrossFieldSuccess-4     1328          1273          -4.14%
BenchmarkStructSimpleCrossStructCrossFieldFailure-4     1949          1896          -2.72%
BenchmarkStructSimpleSuccess-4                          559           523           -6.44%
BenchmarkStructSimpleFailure-4                          1334          1311          -1.72%
BenchmarkStructSimpleSuccessParallel-4                  148           137           -7.43%
BenchmarkStructSimpleFailureParallel-4                  631           591           -6.34%
BenchmarkStructComplexSuccess-4                         3476          3500          +0.69%
BenchmarkStructComplexFailure-4                         8467          8406          -0.72%
BenchmarkStructComplexSuccessParallel-4                 1098          1012          -7.83%
BenchmarkStructComplexFailureParallel-4                 3113          3121          +0.26%

benchmark                                               old allocs     new allocs     delta
BenchmarkFieldSuccess-4                                 0              0              +0.00%
BenchmarkFieldFailure-4                                 4              4              +0.00%
BenchmarkFieldDiveSuccess-4                             28             28             +0.00%
BenchmarkFieldDiveFailure-4                             32             32             +0.00%
BenchmarkFieldCustomTypeSuccess-4                       2              2              +0.00%
BenchmarkFieldCustomTypeFailure-4                       4              4              +0.00%
BenchmarkFieldOrTagSuccess-4                            1              1              +0.00%
BenchmarkFieldOrTagFailure-4                            6              6              +0.00%
BenchmarkStructLevelValidationSuccess-4                 5              5              +0.00%
BenchmarkStructLevelValidationFailure-4                 5              5              +0.00%
BenchmarkStructSimpleCustomTypeSuccess-4                3              3              +0.00%
BenchmarkStructSimpleCustomTypeFailure-4                9              9              +0.00%
BenchmarkStructPartialSuccess-4                         9              9              +0.00%
BenchmarkStructPartialFailure-4                         14             14             +0.00%
BenchmarkStructExceptSuccess-4                          7              7              +0.00%
BenchmarkStructExceptFailure-4                          9              9              +0.00%
BenchmarkStructSimpleCrossFieldSuccess-4                4              4              +0.00%
BenchmarkStructSimpleCrossFieldFailure-4                9              9              +0.00%
BenchmarkStructSimpleCrossStructCrossFieldSuccess-4     7              7              +0.00%
BenchmarkStructSimpleCrossStructCrossFieldFailure-4     12             12             +0.00%
BenchmarkStructSimpleSuccess-4                          1              1              +0.00%
BenchmarkStructSimpleFailure-4                          9              9              +0.00%
BenchmarkStructSimpleSuccessParallel-4                  1              1              +0.00%
BenchmarkStructSimpleFailureParallel-4                  9              9              +0.00%
BenchmarkStructComplexSuccess-4                         15             15             +0.00%
BenchmarkStructComplexFailure-4                         60             60             +0.00%
BenchmarkStructComplexSuccessParallel-4                 15             15             +0.00%
BenchmarkStructComplexFailureParallel-4                 60             60             +0.00%

benchmark                                               old bytes     new bytes     delta
BenchmarkFieldSuccess-4                                 0             0             +0.00%
BenchmarkFieldFailure-4                                 432           432           +0.00%
BenchmarkFieldDiveSuccess-4                             464           464           +0.00%
BenchmarkFieldDiveFailure-4                             896           896           +0.00%
BenchmarkFieldCustomTypeSuccess-4                       32            32            +0.00%
BenchmarkFieldCustomTypeFailure-4                       432           432           +0.00%
BenchmarkFieldOrTagSuccess-4                            4             4             +0.00%
BenchmarkFieldOrTagFailure-4                            448           448           +0.00%
BenchmarkStructLevelValidationSuccess-4                 160           160           +0.00%
BenchmarkStructLevelValidationFailure-4                 160           160           +0.00%
BenchmarkStructSimpleCustomTypeSuccess-4                36            36            +0.00%
BenchmarkStructSimpleCustomTypeFailure-4                640           640           +0.00%
BenchmarkStructPartialSuccess-4                         336           336           +0.00%
BenchmarkStructPartialFailure-4                         794           794           +0.00%
BenchmarkStructExceptSuccess-4                          314           314           +0.00%
BenchmarkStructExceptFailure-4                          336           336           +0.00%
BenchmarkStructSimpleCrossFieldSuccess-4                80            80            +0.00%
BenchmarkStructSimpleCrossFieldFailure-4                536           536           +0.00%
BenchmarkStructSimpleCrossStructCrossFieldSuccess-4     112           112           +0.00%
BenchmarkStructSimpleCrossStructCrossFieldFailure-4     576           576           +0.00%
BenchmarkStructSimpleSuccess-4                          4             4             +0.00%
BenchmarkStructSimpleFailure-4                          640           640           +0.00%
BenchmarkStructSimpleSuccessParallel-4                  4             4             +0.00%
BenchmarkStructSimpleFailureParallel-4                  640           640           +0.00%
BenchmarkStructComplexSuccess-4                         244           244           +0.00%
BenchmarkStructComplexFailure-4                         3608          3608          +0.00%
BenchmarkStructComplexSuccessParallel-4                 244           244           +0.00%
BenchmarkStructComplexFailureParallel-4                 3608          3608          +0.00%

```
pull/252/head
joeybloggs 9 years ago
parent 330b12dacd
commit 4ce4d1cd71
  1. 49
      cache.go
  2. 58
      validator.go

@ -8,6 +8,18 @@ import (
"sync/atomic"
)
type tagType uint8
const (
typeDefault tagType = iota
typeOmitEmpty
typeNoStructLevel
typeStructOnly
typeDive
typeOr
typeExists
)
type structCache struct {
lock sync.Mutex
m atomic.Value // map[reflect.Type]*cStruct
@ -68,20 +80,15 @@ type cField struct {
// TODO: investigate using enum instead of so many booleans, may be faster
// but let's get the new cache system working first
type cTag struct {
tag string
aliasTag string
actualAliasTag string
param string
hasAlias bool
isOmitEmpty bool
isNoStructLevel bool
isStructOnly bool
isDive bool
isOrVal bool
exists bool
hasTag bool
fn Func
next *cTag
tag string
aliasTag string
actualAliasTag string
param string
hasAlias bool
typeof tagType
hasTag bool
fn Func
next *cTag
}
// TODO: eliminate get and set functions from cache, they are pure overhead for nicer syntax.
@ -198,23 +205,23 @@ func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias s
switch t {
case diveTag:
current.isDive = true
current.typeof = typeDive
continue
case omitempty:
current.isOmitEmpty = true
current.typeof = typeOmitEmpty
continue
case structOnlyTag:
current.isStructOnly = true
current.typeof = typeStructOnly
continue
case noStructLevelTag:
current.isNoStructLevel = true
current.typeof = typeNoStructLevel
continue
case existsTag:
current.exists = true
current.typeof = typeExists
continue
default:
@ -247,7 +254,9 @@ func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias s
panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, fieldName)))
}
current.isOrVal = len(orVals) > 1
if len(orVals) > 1 {
current.typeof = typeOr
}
if len(vals) > 1 {
current.param = strings.Replace(strings.Replace(vals[1], utf8HexComma, ",", -1), utf8Pipe, "|", -1)

@ -548,7 +548,7 @@ func (v *Validate) tranverseStruct(topStruct reflect.Value, currentStruct reflec
// structonly tag present don't tranverseFields
// but must still check and run below struct level validation
// if present
if first || ct == nil || !ct.isStructOnly {
if first || ct == nil || ct.typeof != typeStructOnly {
for _, f := range cs.fields {
@ -584,7 +584,7 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.
return
}
if ct.isOmitEmpty {
if ct.typeof == typeOmitEmpty {
return
}
@ -631,7 +631,7 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.
ct = ct.next
}
if ct != nil && ct.isNoStructLevel {
if ct != nil && ct.typeof == typeNoStructLevel {
return
}
@ -652,12 +652,13 @@ OUTER:
return
}
if ct.exists {
switch ct.typeof {
case typeExists:
ct = ct.next
continue
}
if ct.isOmitEmpty {
case typeOmitEmpty:
if !HasValue(v, topStruct, currentStruct, current, typ, kind, blank) {
return
@ -665,9 +666,8 @@ OUTER:
ct = ct.next
continue
}
if ct.isDive {
case typeDive:
ct = ct.next
@ -692,9 +692,8 @@ OUTER:
}
return
}
if ct.isOrVal {
case typeOr:
errTag := blank
@ -711,7 +710,7 @@ OUTER:
return
}
if !ct.isOrVal {
if ct.typeof != typeOr {
continue OUTER
}
}
@ -755,29 +754,30 @@ OUTER:
ct = ct.next
}
}
if !ct.fn(v, topStruct, currentStruct, current, typ, kind, ct.param) {
default:
if !ct.fn(v, topStruct, currentStruct, current, typ, kind, ct.param) {
ns := errPrefix + cf.Name
ns := errPrefix + cf.Name
errs[ns] = &FieldError{
FieldNamespace: ns,
NameNamespace: nsPrefix + cf.AltName,
Name: cf.AltName,
Field: cf.Name,
Tag: ct.aliasTag,
ActualTag: ct.tag,
Value: current.Interface(),
Param: ct.param,
Type: typ,
Kind: kind,
}
errs[ns] = &FieldError{
FieldNamespace: ns,
NameNamespace: nsPrefix + cf.AltName,
Name: cf.AltName,
Field: cf.Name,
Tag: ct.aliasTag,
ActualTag: ct.tag,
Value: current.Interface(),
Param: ct.param,
Type: typ,
Kind: kind,
}
return
return
}
}
ct = ct.next
ct = ct.next
}
}
}

Loading…
Cancel
Save