diff --git a/benchmarks_test.go b/benchmarks_test.go index 0858548..6852d95 100644 --- a/benchmarks_test.go +++ b/benchmarks_test.go @@ -18,6 +18,20 @@ func BenchmarkFieldSuccess(b *testing.B) { } } +func BenchmarkFieldSuccessParallel(b *testing.B) { + + validate := New() + + s := "1" + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Var(&s, "len=1") + } + }) +} + func BenchmarkFieldFailure(b *testing.B) { validate := New() @@ -30,6 +44,20 @@ func BenchmarkFieldFailure(b *testing.B) { } } +func BenchmarkFieldFailureParallel(b *testing.B) { + + validate := New() + + s := "12" + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Var(&s, "len=1") + } + }) +} + func BenchmarkFieldDiveSuccess(b *testing.B) { validate := New() @@ -43,6 +71,20 @@ func BenchmarkFieldDiveSuccess(b *testing.B) { } } +func BenchmarkFieldDiveSuccessParallel(b *testing.B) { + + validate := New() + + m := []string{"val1", "val2", "val3"} + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Var(m, "required,dive,required") + } + }) +} + func BenchmarkFieldDiveFailure(b *testing.B) { validate := New() @@ -55,6 +97,20 @@ func BenchmarkFieldDiveFailure(b *testing.B) { } } +func BenchmarkFieldDiveFailureParallel(b *testing.B) { + + validate := New() + + m := []string{"val1", "", "val3"} + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Var(m, "required,dive,required") + } + }) +} + func BenchmarkFieldCustomTypeSuccess(b *testing.B) { validate := New() @@ -70,6 +126,23 @@ func BenchmarkFieldCustomTypeSuccess(b *testing.B) { } } +func BenchmarkFieldCustomTypeSuccessParallel(b *testing.B) { + + validate := New() + validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{}) + + val := valuer{ + Name: "1", + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Var(val, "len=1") + } + }) +} + func BenchmarkFieldCustomTypeFailure(b *testing.B) { validate := New() @@ -83,6 +156,21 @@ func BenchmarkFieldCustomTypeFailure(b *testing.B) { } } +func BenchmarkFieldCustomTypeFailureParallel(b *testing.B) { + + validate := New() + validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{}) + + val := valuer{} + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Var(val, "len=1") + } + }) +} + func BenchmarkFieldOrTagSuccess(b *testing.B) { validate := New() @@ -95,6 +183,20 @@ func BenchmarkFieldOrTagSuccess(b *testing.B) { } } +func BenchmarkFieldOrTagSuccessParallel(b *testing.B) { + + validate := New() + + s := "rgba(0,0,0,1)" + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Var(s, "rgb|rgba") + } + }) +} + func BenchmarkFieldOrTagFailure(b *testing.B) { validate := New() @@ -107,6 +209,20 @@ func BenchmarkFieldOrTagFailure(b *testing.B) { } } +func BenchmarkFieldOrTagFailureParallel(b *testing.B) { + + validate := New() + + s := "#000" + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Var(s, "rgb|rgba") + } + }) +} + func BenchmarkStructLevelValidationSuccess(b *testing.B) { validate := New() @@ -122,6 +238,23 @@ func BenchmarkStructLevelValidationSuccess(b *testing.B) { } } +func BenchmarkStructLevelValidationSuccessParallel(b *testing.B) { + + validate := New() + validate.RegisterStructValidation(StructValidationTestStructSuccess, TestStruct{}) + + tst := TestStruct{ + String: "good value", + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Struct(tst) + } + }) +} + func BenchmarkStructLevelValidationFailure(b *testing.B) { validate := New() @@ -137,6 +270,23 @@ func BenchmarkStructLevelValidationFailure(b *testing.B) { } } +func BenchmarkStructLevelValidationFailureParallel(b *testing.B) { + + validate := New() + validate.RegisterStructValidation(StructValidationTestStruct, TestStruct{}) + + tst := TestStruct{ + String: "good value", + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Struct(tst) + } + }) +} + func BenchmarkStructSimpleCustomTypeSuccess(b *testing.B) { validate := New() @@ -159,6 +309,30 @@ func BenchmarkStructSimpleCustomTypeSuccess(b *testing.B) { } } +func BenchmarkStructSimpleCustomTypeSuccessParallel(b *testing.B) { + + validate := New() + validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{}) + + val := valuer{ + Name: "1", + } + + type Foo struct { + Valuer valuer `validate:"len=1"` + IntValue int `validate:"min=5,max=10"` + } + + validFoo := &Foo{Valuer: val, IntValue: 7} + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Struct(validFoo) + } + }) +} + func BenchmarkStructSimpleCustomTypeFailure(b *testing.B) { validate := New() @@ -179,6 +353,28 @@ func BenchmarkStructSimpleCustomTypeFailure(b *testing.B) { } } +func BenchmarkStructSimpleCustomTypeFailureParallel(b *testing.B) { + + validate := New() + validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{}) + + val := valuer{} + + type Foo struct { + Valuer valuer `validate:"len=1"` + IntValue int `validate:"min=5,max=10"` + } + + validFoo := &Foo{Valuer: val, IntValue: 3} + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Struct(validate.Struct(validFoo)) + } + }) +} + func BenchmarkStructPartialSuccess(b *testing.B) { validate := New() @@ -198,6 +394,27 @@ func BenchmarkStructPartialSuccess(b *testing.B) { } } +func BenchmarkStructPartialSuccessParallel(b *testing.B) { + + validate := New() + + type Test struct { + Name string `validate:"required"` + NickName string `validate:"required"` + } + + test := &Test{ + Name: "Joey Bloggs", + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.StructPartial(test, "Name") + } + }) +} + func BenchmarkStructPartialFailure(b *testing.B) { validate := New() @@ -217,6 +434,27 @@ func BenchmarkStructPartialFailure(b *testing.B) { } } +func BenchmarkStructPartialFailureParallel(b *testing.B) { + + validate := New() + + type Test struct { + Name string `validate:"required"` + NickName string `validate:"required"` + } + + test := &Test{ + Name: "Joey Bloggs", + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.StructPartial(test, "NickName") + } + }) +} + func BenchmarkStructExceptSuccess(b *testing.B) { validate := New() @@ -232,8 +470,29 @@ func BenchmarkStructExceptSuccess(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - validate.StructPartial(test, "Nickname") + validate.StructExcept(test, "Nickname") + } +} + +func BenchmarkStructExceptSuccessParallel(b *testing.B) { + + validate := New() + + type Test struct { + Name string `validate:"required"` + NickName string `validate:"required"` + } + + test := &Test{ + Name: "Joey Bloggs", } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.StructExcept(test, "NickName") + } + }) } func BenchmarkStructExceptFailure(b *testing.B) { @@ -251,8 +510,29 @@ func BenchmarkStructExceptFailure(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - validate.StructPartial(test, "Name") + validate.StructExcept(test, "Name") + } +} + +func BenchmarkStructExceptFailureParallel(b *testing.B) { + + validate := New() + + type Test struct { + Name string `validate:"required"` + NickName string `validate:"required"` + } + + test := &Test{ + Name: "Joey Bloggs", } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.StructExcept(test, "Name") + } + }) } func BenchmarkStructSimpleCrossFieldSuccess(b *testing.B) { @@ -278,6 +558,31 @@ func BenchmarkStructSimpleCrossFieldSuccess(b *testing.B) { } } +func BenchmarkStructSimpleCrossFieldSuccessParallel(b *testing.B) { + + validate := New() + + type Test struct { + Start time.Time + End time.Time `validate:"gtfield=Start"` + } + + now := time.Now().UTC() + then := now.Add(time.Hour * 5) + + test := &Test{ + Start: now, + End: then, + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Struct(test) + } + }) +} + func BenchmarkStructSimpleCrossFieldFailure(b *testing.B) { validate := New() @@ -301,6 +606,30 @@ func BenchmarkStructSimpleCrossFieldFailure(b *testing.B) { } } +func BenchmarkStructSimpleCrossFieldFailureParallel(b *testing.B) { + + validate := New() + + type Test struct { + Start time.Time + End time.Time `validate:"gtfield=Start"` + } + + now := time.Now().UTC() + then := now.Add(time.Hour * -5) + + test := &Test{ + Start: now, + End: then, + } + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Struct(test) + } + }) +} + func BenchmarkStructSimpleCrossStructCrossFieldSuccess(b *testing.B) { validate := New() @@ -331,6 +660,38 @@ func BenchmarkStructSimpleCrossStructCrossFieldSuccess(b *testing.B) { } } +func BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel(b *testing.B) { + + validate := New() + + type Inner struct { + Start time.Time + } + + type Outer struct { + Inner *Inner + CreatedAt time.Time `validate:"eqcsfield=Inner.Start"` + } + + now := time.Now().UTC() + + inner := &Inner{ + Start: now, + } + + outer := &Outer{ + Inner: inner, + CreatedAt: now, + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Struct(outer) + } + }) +} + func BenchmarkStructSimpleCrossStructCrossFieldFailure(b *testing.B) { validate := New() @@ -362,24 +723,40 @@ func BenchmarkStructSimpleCrossStructCrossFieldFailure(b *testing.B) { } } -func BenchmarkStructSimpleSuccess(b *testing.B) { +func BenchmarkStructSimpleCrossStructCrossFieldFailureParallel(b *testing.B) { validate := New() - type Foo struct { - StringValue string `validate:"min=5,max=10"` - IntValue int `validate:"min=5,max=10"` + type Inner struct { + Start time.Time } - validFoo := &Foo{StringValue: "Foobar", IntValue: 7} + type Outer struct { + Inner *Inner + CreatedAt time.Time `validate:"eqcsfield=Inner.Start"` + } - b.ResetTimer() - for n := 0; n < b.N; n++ { - validate.Struct(validFoo) + now := time.Now().UTC() + then := now.Add(time.Hour * 5) + + inner := &Inner{ + Start: then, + } + + outer := &Outer{ + Inner: inner, + CreatedAt: now, } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Struct(outer) + } + }) } -func BenchmarkStructSimpleFailure(b *testing.B) { +func BenchmarkStructSimpleSuccess(b *testing.B) { validate := New() @@ -388,11 +765,11 @@ func BenchmarkStructSimpleFailure(b *testing.B) { IntValue int `validate:"min=5,max=10"` } - invalidFoo := &Foo{StringValue: "Fo", IntValue: 3} + validFoo := &Foo{StringValue: "Foobar", IntValue: 7} b.ResetTimer() for n := 0; n < b.N; n++ { - validate.Struct(invalidFoo) + validate.Struct(validFoo) } } @@ -415,6 +792,23 @@ func BenchmarkStructSimpleSuccessParallel(b *testing.B) { }) } +func BenchmarkStructSimpleFailure(b *testing.B) { + + validate := New() + + type Foo struct { + StringValue string `validate:"min=5,max=10"` + IntValue int `validate:"min=5,max=10"` + } + + invalidFoo := &Foo{StringValue: "Fo", IntValue: 3} + + b.ResetTimer() + for n := 0; n < b.N; n++ { + validate.Struct(invalidFoo) + } +} + func BenchmarkStructSimpleFailureParallel(b *testing.B) { validate := New() @@ -471,40 +865,6 @@ func BenchmarkStructComplexSuccess(b *testing.B) { } } -func BenchmarkStructComplexFailure(b *testing.B) { - - validate := New() - - tFail := &TestString{ - Required: "", - Len: "", - Min: "", - Max: "12345678901", - MinMax: "", - Lt: "0123456789", - Lte: "01234567890", - Gt: "1", - Gte: "1", - OmitEmpty: "12345678901", - Sub: &SubTest{ - Test: "", - }, - Anonymous: struct { - A string `validate:"required"` - }{ - A: "", - }, - Iface: &Impl{ - F: "12", - }, - } - - b.ResetTimer() - for n := 0; n < b.N; n++ { - validate.Struct(tFail) - } -} - func BenchmarkStructComplexSuccessParallel(b *testing.B) { validate := New() @@ -544,6 +904,40 @@ func BenchmarkStructComplexSuccessParallel(b *testing.B) { }) } +func BenchmarkStructComplexFailure(b *testing.B) { + + validate := New() + + tFail := &TestString{ + Required: "", + Len: "", + Min: "", + Max: "12345678901", + MinMax: "", + Lt: "0123456789", + Lte: "01234567890", + Gt: "1", + Gte: "1", + OmitEmpty: "12345678901", + Sub: &SubTest{ + Test: "", + }, + Anonymous: struct { + A string `validate:"required"` + }{ + A: "", + }, + Iface: &Impl{ + F: "12", + }, + } + + b.ResetTimer() + for n := 0; n < b.N; n++ { + validate.Struct(tFail) + } +} + func BenchmarkStructComplexFailureParallel(b *testing.B) { validate := New()