From 0862513fbf5d9362b2f8443bf601f6ad72ea5c96 Mon Sep 17 00:00:00 2001 From: joeybloggs Date: Wed, 6 Jan 2016 09:29:50 -0500 Subject: [PATCH] Add some string check optimizations * was using len(string) for some blank checks instead of string == "" --- README.md | 56 ++++++++++++++++++++++++++-------------------------- baked_in.go | 2 +- util.go | 11 ++++++----- validator.go | 30 ++++++++++++++-------------- 4 files changed, 50 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index e8e1cdd..2e56559 100644 --- a/README.md +++ b/README.md @@ -312,34 +312,34 @@ Benchmarks ```go go test -cpu=4 -bench=. -benchmem=true PASS -BenchmarkFieldSuccess-4 10000000 173 ns/op 0 B/op 0 allocs/op -BenchmarkFieldFailure-4 2000000 730 ns/op 432 B/op 4 allocs/op -BenchmarkFieldDiveSuccess-4 500000 3180 ns/op 480 B/op 27 allocs/op -BenchmarkFieldDiveFailure-4 500000 3844 ns/op 912 B/op 31 allocs/op -BenchmarkFieldCustomTypeSuccess-4 5000000 365 ns/op 32 B/op 2 allocs/op -BenchmarkFieldCustomTypeFailure-4 2000000 705 ns/op 432 B/op 4 allocs/op -BenchmarkFieldOrTagSuccess-4 1000000 1275 ns/op 16 B/op 1 allocs/op -BenchmarkFieldOrTagFailure-4 1000000 1174 ns/op 464 B/op 6 allocs/op -BenchmarkStructLevelValidationSuccess-4 2000000 800 ns/op 192 B/op 7 allocs/op -BenchmarkStructLevelValidationFailure-4 1000000 1495 ns/op 688 B/op 13 allocs/op -BenchmarkStructSimpleCustomTypeSuccess-4 1000000 1048 ns/op 96 B/op 6 allocs/op -BenchmarkStructSimpleCustomTypeFailure-4 1000000 1730 ns/op 736 B/op 14 allocs/op -BenchmarkStructPartialSuccess-4 1000000 1362 ns/op 400 B/op 11 allocs/op -BenchmarkStructPartialFailure-4 1000000 1993 ns/op 864 B/op 17 allocs/op -BenchmarkStructExceptSuccess-4 1000000 1067 ns/op 352 B/op 8 allocs/op -BenchmarkStructExceptFailure-4 1000000 1352 ns/op 400 B/op 11 allocs/op -BenchmarkStructSimpleCrossFieldSuccess-4 1000000 1147 ns/op 144 B/op 7 allocs/op -BenchmarkStructSimpleCrossFieldFailure-4 1000000 1815 ns/op 624 B/op 13 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldSuccess-4 1000000 1779 ns/op 208 B/op 11 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldFailure-4 500000 2465 ns/op 688 B/op 17 allocs/op -BenchmarkStructSimpleSuccess-4 2000000 980 ns/op 64 B/op 4 allocs/op -BenchmarkStructSimpleFailure-4 1000000 1778 ns/op 736 B/op 14 allocs/op -BenchmarkStructSimpleSuccessParallel-4 5000000 313 ns/op 64 B/op 4 allocs/op -BenchmarkStructSimpleFailureParallel-4 2000000 859 ns/op 736 B/op 14 allocs/op -BenchmarkStructComplexSuccess-4 200000 5781 ns/op 592 B/op 33 allocs/op -BenchmarkStructComplexFailure-4 200000 11816 ns/op 4216 B/op 88 allocs/op -BenchmarkStructComplexSuccessParallel-4 1000000 2003 ns/op 592 B/op 33 allocs/op -BenchmarkStructComplexFailureParallel-4 300000 5628 ns/op 4216 B/op 88 allocs/op +BenchmarkFieldSuccess-4 10000000 176 ns/op 0 B/op 0 allocs/op +BenchmarkFieldFailure-4 2000000 727 ns/op 432 B/op 4 allocs/op +BenchmarkFieldDiveSuccess-4 500000 3220 ns/op 480 B/op 27 allocs/op +BenchmarkFieldDiveFailure-4 500000 3823 ns/op 912 B/op 31 allocs/op +BenchmarkFieldCustomTypeSuccess-4 5000000 368 ns/op 32 B/op 2 allocs/op +BenchmarkFieldCustomTypeFailure-4 2000000 699 ns/op 432 B/op 4 allocs/op +BenchmarkFieldOrTagSuccess-4 1000000 1265 ns/op 16 B/op 1 allocs/op +BenchmarkFieldOrTagFailure-4 1000000 1182 ns/op 464 B/op 6 allocs/op +BenchmarkStructLevelValidationSuccess-4 2000000 739 ns/op 176 B/op 6 allocs/op +BenchmarkStructLevelValidationFailure-4 1000000 1368 ns/op 640 B/op 11 allocs/op +BenchmarkStructSimpleCustomTypeSuccess-4 2000000 965 ns/op 80 B/op 5 allocs/op +BenchmarkStructSimpleCustomTypeFailure-4 1000000 1561 ns/op 688 B/op 11 allocs/op +BenchmarkStructPartialSuccess-4 1000000 1285 ns/op 384 B/op 10 allocs/op +BenchmarkStructPartialFailure-4 1000000 1879 ns/op 832 B/op 15 allocs/op +BenchmarkStructExceptSuccess-4 2000000 1038 ns/op 336 B/op 7 allocs/op +BenchmarkStructExceptFailure-4 1000000 1330 ns/op 384 B/op 10 allocs/op +BenchmarkStructSimpleCrossFieldSuccess-4 1000000 1081 ns/op 128 B/op 6 allocs/op +BenchmarkStructSimpleCrossFieldFailure-4 1000000 1737 ns/op 592 B/op 11 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldSuccess-4 1000000 1790 ns/op 192 B/op 10 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldFailure-4 500000 2431 ns/op 656 B/op 15 allocs/op +BenchmarkStructSimpleSuccess-4 2000000 950 ns/op 48 B/op 3 allocs/op +BenchmarkStructSimpleFailure-4 1000000 1672 ns/op 688 B/op 11 allocs/op +BenchmarkStructSimpleSuccessParallel-4 5000000 271 ns/op 48 B/op 3 allocs/op +BenchmarkStructSimpleFailureParallel-4 2000000 670 ns/op 688 B/op 11 allocs/op +BenchmarkStructComplexSuccess-4 300000 5828 ns/op 544 B/op 32 allocs/op +BenchmarkStructComplexFailure-4 200000 11382 ns/op 3912 B/op 77 allocs/op +BenchmarkStructComplexSuccessParallel-4 1000000 1739 ns/op 544 B/op 32 allocs/op +BenchmarkStructComplexFailureParallel-4 300000 4682 ns/op 3912 B/op 77 allocs/op ``` How to Contribute diff --git a/baked_in.go b/baked_in.go index 9338cf5..e9fc9a4 100644 --- a/baked_in.go +++ b/baked_in.go @@ -756,7 +756,7 @@ func IsURL(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Va return false } - if len(url.Scheme) == 0 { + if url.Scheme == blank { return false } diff --git a/util.go b/util.go index abe6b03..ce01c7c 100644 --- a/util.go +++ b/util.go @@ -8,6 +8,7 @@ import ( ) const ( + dash = "-" blank = "" namespaceSeparator = "." leftBracket = "[" @@ -86,7 +87,7 @@ func (v *Validate) GetStructFieldOK(current reflect.Value, namespace string) (re return current, kind, false } - if len(namespace) == 0 { + if namespace == blank { return current, kind, true } @@ -262,7 +263,7 @@ func (v *Validate) parseStruct(current reflect.Value, sName string) *cachedStruc fld = typ.Field(i) - if len(fld.PkgPath) != 0 { + if fld.PkgPath != blank { continue } @@ -273,7 +274,7 @@ func (v *Validate) parseStruct(current reflect.Value, sName string) *cachedStruc } customName = fld.Name - if len(v.fieldNameTag) != 0 { + if v.fieldNameTag != blank { name := strings.SplitN(fld.Tag.Get(v.fieldNameTag), ",", 2)[0] @@ -309,7 +310,7 @@ func (v *Validate) parseTags(tag, fieldName string) *cachedTag { func (v *Validate) parseTagsRecursive(cTag *cachedTag, tag, fieldName, alias string, isAlias bool) bool { - if len(tag) == 0 { + if tag == blank { return true } @@ -365,7 +366,7 @@ func (v *Validate) parseTagsRecursive(cTag *cachedTag, tag, fieldName, alias str tagVal.tag = alias } - if len(key) == 0 { + if key == blank { panic(strings.TrimSpace(fmt.Sprintf(invalidValidation, fieldName))) } diff --git a/validator.go b/validator.go index a24143b..d3cc543 100644 --- a/validator.go +++ b/validator.go @@ -94,15 +94,15 @@ func (sl *StructLevel) ReportError(field reflect.Value, fieldName string, custom field, kind := sl.v.ExtractType(field) - if len(fieldName) == 0 { + if fieldName == blank { panic(fieldNameRequired) } - if len(customName) == 0 { + if customName == blank { customName = fieldName } - if len(tag) == 0 { + if tag == blank { panic(tagRequired) } @@ -270,7 +270,7 @@ func (v *Validate) RegisterStructValidation(fn StructLevelFunc, types ...interfa func (v *Validate) RegisterValidation(key string, fn Func) error { v.initCheck() - if len(key) == 0 { + if key == blank { return errors.New("Function Key cannot be empty") } @@ -435,7 +435,7 @@ func (v *Validate) StructExcept(current interface{}, fields ...string) error { m := map[string]*struct{}{} for _, key := range fields { - m[name+"."+key] = emptyStructPtr + m[name+namespaceSeparator+key] = emptyStructPtr } errs := v.errsPool.Get().(ValidationErrors) @@ -486,10 +486,10 @@ func (v *Validate) tranverseStruct(topStruct reflect.Value, currentStruct reflec sName := typ.Name() if useStructName { - errPrefix += sName + "." + errPrefix += sName + namespaceSeparator - if v.fieldNameTag != "" { - nsPrefix += sName + "." + if v.fieldNameTag != blank { + nsPrefix += sName + namespaceSeparator } } @@ -502,7 +502,7 @@ func (v *Validate) tranverseStruct(topStruct reflect.Value, currentStruct reflec // is anonymous struct, cannot parse or cache as // it has no name to index by - if len(sName) == 0 { + if sName == blank { var customName string var ok bool @@ -512,7 +512,7 @@ func (v *Validate) tranverseStruct(topStruct reflect.Value, currentStruct reflec fld = typ.Field(i) - if len(fld.PkgPath) != 0 { + if fld.PkgPath != blank { continue } @@ -527,12 +527,12 @@ func (v *Validate) tranverseStruct(topStruct reflect.Value, currentStruct reflec customName = fld.Name - if v.fieldNameTag != "" { + if v.fieldNameTag != blank { name := strings.SplitN(fld.Tag.Get(v.fieldNameTag), ",", 2)[0] // dash check is for json "-" means don't output in json - if name != "" && name != "-" { + if name != blank && name != dash { customName = name } } @@ -595,7 +595,7 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect. return } - if len(tag) > 0 { + if tag != blank { ns := errPrefix + name @@ -643,12 +643,12 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect. return } - v.tranverseStruct(topStruct, current, current, errPrefix+name+".", nsPrefix+customName+".", errs, false, partial, exclude, includeExclude, cTag.isStructOnly) + v.tranverseStruct(topStruct, current, current, errPrefix+name+namespaceSeparator, nsPrefix+customName+namespaceSeparator, errs, false, partial, exclude, includeExclude, cTag.isStructOnly) return } } - if len(tag) == 0 { + if tag == blank { return }