💯Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
validator/validator.go

486 lines
11 KiB

package validator
import (
"context"
"fmt"
"reflect"
"strconv"
)
5 years ago
// per validate construct
8 years ago
type validate struct {
v *Validate
top reflect.Value
ns []byte
actualNs []byte
errs ValidationErrors
includeExclude map[string]struct{} // reset only if StructPartial or StructExcept are called, no need otherwise
ffn FilterFunc
slflParent reflect.Value // StructLevel & FieldLevel
slCurrent reflect.Value // StructLevel & FieldLevel
flField reflect.Value // StructLevel & FieldLevel
cf *cField // StructLevel & FieldLevel
ct *cTag // StructLevel & FieldLevel
misc []byte // misc reusable
str1 string // misc reusable
str2 string // misc reusable
fldIsPointer bool // StructLevel & FieldLevel
8 years ago
isPartial bool
hasExcludes bool
}
8 years ago
// parent and current will be the same the first run of validateStruct
func (v *validate) validateStruct(ctx context.Context, parent reflect.Value, current reflect.Value, typ reflect.Type, ns []byte, structNs []byte, ct *cTag) {
8 years ago
cs, ok := v.v.structCache.Get(typ)
if !ok {
8 years ago
cs = v.v.extractStructCache(current, typ.Name())
}
if len(ns) == 0 && len(cs.name) != 0 {
ns = append(ns, cs.name...)
8 years ago
ns = append(ns, '.')
structNs = append(structNs, cs.name...)
structNs = append(structNs, '.')
}
8 years ago
// ct is nil on top level struct, and structs as fields that have no tag info
// so if nil or if not nil and the structonly tag isn't present
if ct == nil || ct.typeof != typeStructOnly {
change field cache to array - errors now come out in order for unit tests - speed improvement using array vs map benchmark old ns/op new ns/op delta BenchmarkFieldSuccess-8 101 100 -0.99% BenchmarkFieldSuccessParallel-8 33.2 33.7 +1.51% BenchmarkFieldFailure-8 323 332 +2.79% BenchmarkFieldFailureParallel-8 112 113 +0.89% BenchmarkFieldDiveSuccess-8 719 714 -0.70% BenchmarkFieldDiveSuccessParallel-8 230 225 -2.17% BenchmarkFieldDiveFailure-8 1001 987 -1.40% BenchmarkFieldDiveFailureParallel-8 323 317 -1.86% BenchmarkFieldCustomTypeSuccess-8 263 264 +0.38% BenchmarkFieldCustomTypeSuccessParallel-8 82.6 81.4 -1.45% BenchmarkFieldCustomTypeFailure-8 327 328 +0.31% BenchmarkFieldCustomTypeFailureParallel-8 116 116 +0.00% BenchmarkFieldOrTagSuccess-8 871 878 +0.80% BenchmarkFieldOrTagSuccessParallel-8 394 402 +2.03% BenchmarkFieldOrTagFailure-8 568 569 +0.18% BenchmarkFieldOrTagFailureParallel-8 397 401 +1.01% BenchmarkStructLevelValidationSuccess-8 332 267 -19.58% BenchmarkStructLevelValidationSuccessParallel-8 105 82.4 -21.52% BenchmarkStructLevelValidationFailure-8 637 557 -12.56% BenchmarkStructLevelValidationFailureParallel-8 260 226 -13.08% BenchmarkStructSimpleCustomTypeSuccess-8 525 452 -13.90% BenchmarkStructSimpleCustomTypeSuccessParallel-8 155 144 -7.10% BenchmarkStructSimpleCustomTypeFailure-8 828 738 -10.87% BenchmarkStructSimpleCustomTypeFailureParallel-8 345 285 -17.39% BenchmarkStructFilteredSuccess-8 744 664 -10.75% BenchmarkStructFilteredSuccessParallel-8 274 257 -6.20% BenchmarkStructFilteredFailure-8 595 517 -13.11% BenchmarkStructFilteredFailureParallel-8 250 195 -22.00% BenchmarkStructPartialSuccess-8 674 608 -9.79% BenchmarkStructPartialSuccessParallel-8 256 225 -12.11% BenchmarkStructPartialFailure-8 928 848 -8.62% BenchmarkStructPartialFailureParallel-8 399 360 -9.77% BenchmarkStructExceptSuccess-8 1076 934 -13.20% BenchmarkStructExceptSuccessParallel-8 237 200 -15.61% BenchmarkStructExceptFailure-8 873 787 -9.85% BenchmarkStructExceptFailureParallel-8 365 333 -8.77% BenchmarkStructSimpleCrossFieldSuccess-8 539 489 -9.28% BenchmarkStructSimpleCrossFieldSuccessParallel-8 201 168 -16.42% BenchmarkStructSimpleCrossFieldFailure-8 788 709 -10.03% BenchmarkStructSimpleCrossFieldFailureParallel-8 322 299 -7.14% BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 795 683 -14.09% BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 241 211 -12.45% BenchmarkStructSimpleCrossStructCrossFieldFailure-8 1110 940 -15.32% BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 399 333 -16.54% BenchmarkStructSimpleSuccess-8 367 285 -22.34% BenchmarkStructSimpleSuccessParallel-8 108 91.0 -15.74% BenchmarkStructSimpleFailure-8 776 698 -10.05% BenchmarkStructSimpleFailureParallel-8 307 284 -7.49% BenchmarkStructComplexSuccess-8 2224 1622 -27.07% BenchmarkStructComplexSuccessParallel-8 718 526 -26.74% BenchmarkStructComplexFailure-8 5350 4717 -11.83% BenchmarkStructComplexFailureParallel-8 2097 1853 -11.64%
8 years ago
var f *cField
for i := 0; i < len(cs.fields); i++ {
f = cs.fields[i]
8 years ago
if v.isPartial {
8 years ago
if v.ffn != nil {
// used with StructFiltered
if v.ffn(append(structNs, f.name...)) {
continue
}
} else {
// used with StructPartial & StructExcept
_, ok = v.includeExclude[string(append(structNs, f.name...))]
8 years ago
if (ok && v.hasExcludes) || (!ok && !v.hasExcludes) {
continue
}
}
}
v.traverseField(ctx, current, current.Field(f.idx), ns, structNs, f, f.cTags)
}
}
// check if any struct level validations, after all field validations already checked.
8 years ago
// first iteration will have no info about nostructlevel tag, and is checked prior to
// calling the next iteration of validateStruct called from traverseField.
if cs.fn != nil {
8 years ago
v.slflParent = parent
v.slCurrent = current
v.ns = ns
v.actualNs = structNs
8 years ago
cs.fn(ctx, v)
}
}
// traverseField validates any field, be it a struct or single field, ensures it's validity and passes it along to be validated via it's tag options
func (v *validate) traverseField(ctx context.Context, parent reflect.Value, current reflect.Value, ns []byte, structNs []byte, cf *cField, ct *cTag) {
var typ reflect.Type
8 years ago
var kind reflect.Kind
current, kind, v.fldIsPointer = v.extractTypeInternal(current, false)
switch kind {
case reflect.Ptr, reflect.Interface, reflect.Invalid:
if ct == nil {
return
}
if ct.typeof == typeOmitEmpty || ct.typeof == typeIsDefault {
return
}
if ct.hasTag {
if kind == reflect.Invalid {
v.str1 = string(append(ns, cf.altName...))
if v.v.hasTagNameFunc {
v.str2 = string(append(structNs, cf.name...))
} else {
v.str2 = v.str1
}
v.errs = append(v.errs,
&fieldError{
v: v.v,
tag: ct.aliasTag,
actualTag: ct.tag,
ns: v.str1,
structNs: v.str2,
fieldLen: uint8(len(cf.altName)),
structfieldLen: uint8(len(cf.name)),
param: ct.param,
kind: kind,
},
)
return
}
v.str1 = string(append(ns, cf.altName...))
if v.v.hasTagNameFunc {
v.str2 = string(append(structNs, cf.name...))
} else {
v.str2 = v.str1
}
if !ct.runValidationWhenNil {
8 years ago
v.errs = append(v.errs,
&fieldError{
v: v.v,
tag: ct.aliasTag,
actualTag: ct.tag,
ns: v.str1,
structNs: v.str2,
fieldLen: uint8(len(cf.altName)),
structfieldLen: uint8(len(cf.name)),
value: current.Interface(),
param: ct.param,
kind: kind,
typ: current.Type(),
8 years ago
},
)
return
}
}
case reflect.Struct:
8 years ago
typ = current.Type()
if !typ.ConvertibleTo(timeType) {
if ct != nil {
if ct.typeof == typeStructOnly {
goto CONTINUE
} else if ct.typeof == typeIsDefault {
// set Field Level fields
v.slflParent = parent
v.flField = current
v.cf = cf
v.ct = ct
if !ct.fn(ctx, v) {
v.str1 = string(append(ns, cf.altName...))
if v.v.hasTagNameFunc {
v.str2 = string(append(structNs, cf.name...))
} else {
v.str2 = v.str1
}
v.errs = append(v.errs,
&fieldError{
v: v.v,
tag: ct.aliasTag,
actualTag: ct.tag,
ns: v.str1,
structNs: v.str2,
fieldLen: uint8(len(cf.altName)),
structfieldLen: uint8(len(cf.name)),
value: current.Interface(),
param: ct.param,
kind: kind,
typ: typ,
},
)
return
}
}
ct = ct.next
}
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% ```
8 years ago
if ct != nil && ct.typeof == typeNoStructLevel {
return
}
CONTINUE:
// if len == 0 then validating using 'Var' or 'VarWithValue'
// Var - doesn't make much sense to do it that way, should call 'Struct', but no harm...
// VarWithField - this allows for validating against each field within the struct against a specific value
// pretty handy in certain situations
if len(cf.name) > 0 {
ns = append(append(ns, cf.altName...), '.')
structNs = append(append(structNs, cf.name...), '.')
}
v.validateStruct(ctx, parent, current, typ, ns, structNs, ct)
return
}
}
if ct == nil || !ct.hasTag {
return
}
typ = current.Type()
OUTER:
for {
if ct == nil {
return
}
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% ```
8 years ago
switch ct.typeof {
case typeOmitEmpty:
8 years ago
// set Field Level fields
v.slflParent = parent
v.flField = current
v.cf = cf
v.ct = ct
8 years ago
if !hasValue(v) {
return
}
ct = ct.next
continue
case typeEndKeys:
return
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% ```
8 years ago
case typeDive:
ct = ct.next
// traverse slice or map here
// or panic ;)
switch kind {
case reflect.Slice, reflect.Array:
8 years ago
var i64 int64
reusableCF := &cField{}
for i := 0; i < current.Len(); i++ {
8 years ago
i64 = int64(i)
v.misc = append(v.misc[0:0], cf.name...)
v.misc = append(v.misc, '[')
8 years ago
v.misc = strconv.AppendInt(v.misc, i64, 10)
v.misc = append(v.misc, ']')
reusableCF.name = string(v.misc)
if cf.namesEqual {
reusableCF.altName = reusableCF.name
} else {
v.misc = append(v.misc[0:0], cf.altName...)
v.misc = append(v.misc, '[')
v.misc = strconv.AppendInt(v.misc, i64, 10)
v.misc = append(v.misc, ']')
reusableCF.altName = string(v.misc)
}
v.traverseField(ctx, parent, current.Index(i), ns, structNs, reusableCF, ct)
}
code cleanup + add missing tag cache with FieldWith func Still looking good: ``` benchmark old ns/op new ns/op delta BenchmarkFieldSuccess-4 167 119 -28.74% BenchmarkFieldFailure-4 701 650 -7.28% BenchmarkFieldDiveSuccess-4 2937 2482 -15.49% BenchmarkFieldDiveFailure-4 3536 3046 -13.86% BenchmarkFieldCustomTypeSuccess-4 341 296 -13.20% BenchmarkFieldCustomTypeFailure-4 679 666 -1.91% BenchmarkFieldOrTagSuccess-4 1157 1124 -2.85% BenchmarkFieldOrTagFailure-4 1109 1036 -6.58% BenchmarkStructLevelValidationSuccess-4 694 554 -20.17% BenchmarkStructLevelValidationFailure-4 1311 558 -57.44% BenchmarkStructSimpleCustomTypeSuccess-4 894 654 -26.85% BenchmarkStructSimpleCustomTypeFailure-4 1496 1286 -14.04% BenchmarkStructPartialSuccess-4 1229 1062 -13.59% BenchmarkStructPartialFailure-4 1838 1639 -10.83% BenchmarkStructExceptSuccess-4 961 919 -4.37% BenchmarkStructExceptFailure-4 1218 1072 -11.99% BenchmarkStructSimpleCrossFieldSuccess-4 954 800 -16.14% BenchmarkStructSimpleCrossFieldFailure-4 1569 1372 -12.56% BenchmarkStructSimpleCrossStructCrossFieldSuccess-4 1588 1274 -19.77% BenchmarkStructSimpleCrossStructCrossFieldFailure-4 2217 1901 -14.25% BenchmarkStructSimpleSuccess-4 925 512 -44.65% BenchmarkStructSimpleFailure-4 1650 1318 -20.12% BenchmarkStructSimpleSuccessParallel-4 261 144 -44.83% BenchmarkStructSimpleFailureParallel-4 758 581 -23.35% BenchmarkStructComplexSuccess-4 5868 3451 -41.19% BenchmarkStructComplexFailure-4 10767 8351 -22.44% BenchmarkStructComplexSuccessParallel-4 1559 1065 -31.69% BenchmarkStructComplexFailureParallel-4 3747 2916 -22.18% ```
8 years ago
case reflect.Map:
var pv string
8 years ago
reusableCF := &cField{}
for _, key := range current.MapKeys() {
pv = fmt.Sprintf("%v", key.Interface())
v.misc = append(v.misc[0:0], cf.name...)
v.misc = append(v.misc, '[')
v.misc = append(v.misc, pv...)
v.misc = append(v.misc, ']')
reusableCF.name = string(v.misc)
if cf.namesEqual {
reusableCF.altName = reusableCF.name
} else {
v.misc = append(v.misc[0:0], cf.altName...)
v.misc = append(v.misc, '[')
v.misc = append(v.misc, pv...)
v.misc = append(v.misc, ']')
reusableCF.altName = string(v.misc)
}
8 years ago
if ct != nil && ct.typeof == typeKeys && ct.keys != nil {
v.traverseField(ctx, parent, key, ns, structNs, reusableCF, ct.keys)
// can be nil when just keys being validated
if ct.next != nil {
v.traverseField(ctx, parent, current.MapIndex(key), ns, structNs, reusableCF, ct.next)
}
} else {
v.traverseField(ctx, parent, current.MapIndex(key), ns, structNs, reusableCF, ct)
}
}
default:
// throw error, if not a slice or map then should not have gotten here
// bad dive tag
panic("dive error! can't dive on a non slice or map")
}
return
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% ```
8 years ago
case typeOr:
v.misc = v.misc[0:0]
for {
8 years ago
// set Field Level fields
v.slflParent = parent
v.flField = current
v.cf = cf
v.ct = ct
8 years ago
if ct.fn(ctx, v) {
if ct.isBlockEnd {
ct = ct.next
continue OUTER
}
// drain rest of the 'or' values, then continue or leave
for {
ct = ct.next
if ct == nil {
return
}
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% ```
8 years ago
if ct.typeof != typeOr {
continue OUTER
}
if ct.isBlockEnd {
ct = ct.next
continue OUTER
}
}
}
v.misc = append(v.misc, '|')
v.misc = append(v.misc, ct.tag...)
if ct.hasParam {
v.misc = append(v.misc, '=')
v.misc = append(v.misc, ct.param...)
}
if ct.isBlockEnd || ct.next == nil {
// if we get here, no valid 'or' value and no more tags
v.str1 = string(append(ns, cf.altName...))
if v.v.hasTagNameFunc {
v.str2 = string(append(structNs, cf.name...))
} else {
v.str2 = v.str1
}
if ct.hasAlias {
8 years ago
v.errs = append(v.errs,
&fieldError{
v: v.v,
tag: ct.aliasTag,
actualTag: ct.actualAliasTag,
ns: v.str1,
structNs: v.str2,
fieldLen: uint8(len(cf.altName)),
structfieldLen: uint8(len(cf.name)),
value: current.Interface(),
param: ct.param,
kind: kind,
typ: typ,
8 years ago
},
)
} else {
8 years ago
tVal := string(v.misc)[1:]
8 years ago
v.errs = append(v.errs,
&fieldError{
v: v.v,
tag: tVal,
actualTag: tVal,
ns: v.str1,
structNs: v.str2,
fieldLen: uint8(len(cf.altName)),
structfieldLen: uint8(len(cf.name)),
value: current.Interface(),
param: ct.param,
kind: kind,
typ: typ,
8 years ago
},
)
}
return
}
ct = ct.next
}
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% ```
8 years ago
default:
8 years ago
// set Field Level fields
v.slflParent = parent
v.flField = current
v.cf = cf
v.ct = ct
8 years ago
if !ct.fn(ctx, v) {
v.str1 = string(append(ns, cf.altName...))
if v.v.hasTagNameFunc {
v.str2 = string(append(structNs, cf.name...))
} else {
v.str2 = v.str1
}
8 years ago
v.errs = append(v.errs,
&fieldError{
v: v.v,
tag: ct.aliasTag,
actualTag: ct.tag,
ns: v.str1,
structNs: v.str2,
fieldLen: uint8(len(cf.altName)),
structfieldLen: uint8(len(cf.name)),
value: current.Interface(),
param: ct.param,
kind: kind,
typ: typ,
8 years ago
},
)
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% ```
8 years ago
return
}
ct = ct.next
}
}
8 years ago
}