Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 21 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,24 +192,28 @@ NOTE: allocations for structs are up from v5, however ns/op for parallel operati
It was a decicion not to cache struct info because although it reduced allocation to v5 levels, it
hurt parallel performance too much.
```go
$ go test -cpu=4 -bench=. -benchmem=true
go test -cpu=4 -bench=. -benchmem=true
PASS
BenchmarkFieldSuccess-4 5000000 318 ns/op 16 B/op 1 allocs/op
BenchmarkFieldFailure-4 5000000 316 ns/op 16 B/op 1 allocs/op
BenchmarkFieldCustomTypeSuccess-4 3000000 492 ns/op 32 B/op 2 allocs/op
BenchmarkFieldCustomTypeFailure-4 2000000 843 ns/op 416 B/op 6 allocs/op
BenchmarkFieldOrTagSuccess-4 500000 2384 ns/op 20 B/op 2 allocs/op
BenchmarkFieldOrTagFailure-4 1000000 1295 ns/op 384 B/op 6 allocs/op
BenchmarkStructSimpleSuccess-4 1000000 1175 ns/op 24 B/op 3 allocs/op
BenchmarkStructSimpleFailure-4 1000000 1822 ns/op 529 B/op 11 allocs/op
BenchmarkStructSimpleCustomTypeSuccess-4 1000000 1302 ns/op 56 B/op 5 allocs/op
BenchmarkStructSimpleCustomTypeFailure-4 1000000 1847 ns/op 577 B/op 13 allocs/op
BenchmarkStructSimpleSuccessParallel-4 5000000 339 ns/op 24 B/op 3 allocs/op
BenchmarkStructSimpleFailureParallel-4 2000000 733 ns/op 529 B/op 11 allocs/op
BenchmarkStructComplexSuccess-4 200000 7104 ns/op 368 B/op 30 allocs/op
BenchmarkStructComplexFailure-4 100000 11996 ns/op 2861 B/op 72 allocs/op
BenchmarkStructComplexSuccessParallel-4 1000000 2252 ns/op 368 B/op 30 allocs/op
BenchmarkStructComplexFailureParallel-4 300000 4691 ns/op 2862 B/op 72 allocs/op
BenchmarkFieldSuccess-4 5000000 337 ns/op 16 B/op 1 allocs/op
BenchmarkFieldFailure-4 5000000 331 ns/op 16 B/op 1 allocs/op
BenchmarkFieldCustomTypeSuccess-4 3000000 497 ns/op 32 B/op 2 allocs/op
BenchmarkFieldCustomTypeFailure-4 2000000 842 ns/op 416 B/op 6 allocs/op
BenchmarkFieldOrTagSuccess-4 500000 2432 ns/op 20 B/op 2 allocs/op
BenchmarkFieldOrTagFailure-4 1000000 1323 ns/op 384 B/op 6 allocs/op
BenchmarkStructSimpleCustomTypeSuccess-4 1000000 1409 ns/op 56 B/op 5 allocs/op
BenchmarkStructSimpleCustomTypeFailure-4 1000000 1876 ns/op 577 B/op 13 allocs/op
BenchmarkStructPartialSuccess-4 1000000 1438 ns/op 384 B/op 13 allocs/op
BenchmarkStructPartialFailure-4 1000000 2040 ns/op 785 B/op 18 allocs/op
BenchmarkStructExceptSuccess-4 1000000 1000 ns/op 368 B/op 11 allocs/op
BenchmarkStructExceptFailure-4 1000000 1431 ns/op 384 B/op 13 allocs/op
BenchmarkStructSimpleSuccess-4 1000000 1375 ns/op 24 B/op 3 allocs/op
BenchmarkStructSimpleFailure-4 1000000 1893 ns/op 529 B/op 11 allocs/op
BenchmarkStructSimpleSuccessParallel-4 5000000 362 ns/op 24 B/op 3 allocs/op
BenchmarkStructSimpleFailureParallel-4 2000000 883 ns/op 529 B/op 11 allocs/op
BenchmarkStructComplexSuccess-4 200000 8237 ns/op 368 B/op 30 allocs/op
BenchmarkStructComplexFailure-4 100000 12617 ns/op 2861 B/op 72 allocs/op
BenchmarkStructComplexSuccessParallel-4 1000000 2398 ns/op 368 B/op 30 allocs/op
BenchmarkStructComplexFailureParallel-4 300000 5733 ns/op 2862 B/op 72 allocs/op
```

How to Contribute
Expand Down
37 changes: 0 additions & 37 deletions baked_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"net"
"net/url"
"reflect"
"strconv"
"strings"
"time"
"unicode/utf8"
Expand Down Expand Up @@ -902,39 +901,3 @@ func hasMaxOf(topStruct reflect.Value, currentStruct reflect.Value, field reflec

return isLte(topStruct, currentStruct, field, fieldType, fieldKind, param)
}

// asInt retuns the parameter as a int64
// or panics if it can't convert
func asInt(param string) int64 {

i, err := strconv.ParseInt(param, 0, 64)
panicIf(err)

return i
}

// asUint returns the parameter as a uint64
// or panics if it can't convert
func asUint(param string) uint64 {

i, err := strconv.ParseUint(param, 0, 64)
panicIf(err)

return i
}

// asFloat returns the parameter as a float64
// or panics if it can't convert
func asFloat(param string) float64 {

i, err := strconv.ParseFloat(param, 64)
panicIf(err)

return i
}

func panicIf(err error) {
if err != nil {
panic(err.Error())
}
}
120 changes: 92 additions & 28 deletions benchmarks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,34 +62,6 @@ func BenchmarkFieldOrTagFailure(b *testing.B) {
}
}

func BenchmarkStructSimpleSuccess(b *testing.B) {

type Foo struct {
StringValue string `validate:"min=5,max=10"`
IntValue int `validate:"min=5,max=10"`
}

validFoo := &Foo{StringValue: "Foobar", IntValue: 7}

for n := 0; n < b.N; n++ {
validate.Struct(validFoo)
}
}

func BenchmarkStructSimpleFailure(b *testing.B) {

type Foo struct {
StringValue string `validate:"min=5,max=10"`
IntValue int `validate:"min=5,max=10"`
}

invalidFoo := &Foo{StringValue: "Fo", IntValue: 3}

for n := 0; n < b.N; n++ {
validate.Struct(invalidFoo)
}
}

func BenchmarkStructSimpleCustomTypeSuccess(b *testing.B) {

customTypes := map[reflect.Type]CustomTypeFunc{}
Expand Down Expand Up @@ -136,6 +108,98 @@ func BenchmarkStructSimpleCustomTypeFailure(b *testing.B) {
}
}

func BenchmarkStructPartialSuccess(b *testing.B) {

type Test struct {
Name string `validate:"required"`
NickName string `validate:"required"`
}

test := &Test{
Name: "Joey Bloggs",
}

for n := 0; n < b.N; n++ {
validate.StructPartial(test, "Name")
}
}

func BenchmarkStructPartialFailure(b *testing.B) {

type Test struct {
Name string `validate:"required"`
NickName string `validate:"required"`
}

test := &Test{
Name: "Joey Bloggs",
}

for n := 0; n < b.N; n++ {
validate.StructPartial(test, "NickName")
}
}

func BenchmarkStructExceptSuccess(b *testing.B) {

type Test struct {
Name string `validate:"required"`
NickName string `validate:"required"`
}

test := &Test{
Name: "Joey Bloggs",
}

for n := 0; n < b.N; n++ {
validate.StructPartial(test, "Nickname")
}
}

func BenchmarkStructExceptFailure(b *testing.B) {

type Test struct {
Name string `validate:"required"`
NickName string `validate:"required"`
}

test := &Test{
Name: "Joey Bloggs",
}

for n := 0; n < b.N; n++ {
validate.StructPartial(test, "Name")
}
}

func BenchmarkStructSimpleSuccess(b *testing.B) {

type Foo struct {
StringValue string `validate:"min=5,max=10"`
IntValue int `validate:"min=5,max=10"`
}

validFoo := &Foo{StringValue: "Foobar", IntValue: 7}

for n := 0; n < b.N; n++ {
validate.Struct(validFoo)
}
}

func BenchmarkStructSimpleFailure(b *testing.B) {

type Foo struct {
StringValue string `validate:"min=5,max=10"`
IntValue int `validate:"min=5,max=10"`
}

invalidFoo := &Foo{StringValue: "Fo", IntValue: 3}

for n := 0; n < b.N; n++ {
validate.Struct(invalidFoo)
}
}

func BenchmarkStructSimpleSuccessParallel(b *testing.B) {

type Foo struct {
Expand Down
2 changes: 1 addition & 1 deletion examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package validator_test
import (
"fmt"

"../validator"
"gopkg.in/bluesuncorp/validator.v6"
)

func ExampleValidate_new() {
Expand Down
82 changes: 82 additions & 0 deletions util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package validator

import (
"reflect"
"strconv"
)

const (
namespaceSeparator = "."
leftBracket = "["
rightBracket = "]"
)

func (v *Validate) extractType(current reflect.Value) (reflect.Value, reflect.Kind) {

switch current.Kind() {
case reflect.Ptr:

if current.IsNil() {
return current, reflect.Ptr
}

return v.extractType(current.Elem())

case reflect.Interface:

if current.IsNil() {
return current, reflect.Interface
}

return v.extractType(current.Elem())

case reflect.Invalid:
return current, reflect.Invalid

default:

if v.config.hasCustomFuncs {
if fn, ok := v.config.CustomTypeFuncs[current.Type()]; ok {
return v.extractType(reflect.ValueOf(fn(current)))
}
}

return current, current.Kind()
}
}

// asInt retuns the parameter as a int64
// or panics if it can't convert
func asInt(param string) int64 {

i, err := strconv.ParseInt(param, 0, 64)
panicIf(err)

return i
}

// asUint returns the parameter as a uint64
// or panics if it can't convert
func asUint(param string) uint64 {

i, err := strconv.ParseUint(param, 0, 64)
panicIf(err)

return i
}

// asFloat returns the parameter as a float64
// or panics if it can't convert
func asFloat(param string) float64 {

i, err := strconv.ParseFloat(param, 64)
panicIf(err)

return i
}

func panicIf(err error) {
if err != nil {
panic(err.Error())
}
}
Loading