Hello Team,
I am raising this issue to get an idea of whether we should choose protovalidate-go or protoc-gen-validate. As reported in other issues, some performance penalty is expected:
I am wondering what the target performance is. I ran a couple of benchmarks to estimate the effective memory utilization increase compared to our baseline. I have three scenarios:
- Message encoding:
370MB
- Message encoding + validation:
5800MB ❗
- Message encoding + optimized validation:
5500MB ❗ (CEL alone accounts for 3600MB)
The payload used for measuring has approximately 50 fields, nested in different configurations.
I'm wondering what we can do on our end to adopt the library:
- Are the reported values within the range of expected utilization?
- Is there a way to disable CEL, for example, if the directive is never used?
- anything on the roadmap to take the resource consumption down?
func BenchmarkMarshalAndValidate(b *testing.B) {
cases := map[string]proto.Message{
"medium": createSampleProtoMessage(),
"large": createLargeProtoMessage(),
}
for hint, msg := range cases {
b.Run(hint, func(b *testing.B) {
validator, err := protovalidate.New()
if err != nil {
b.Fatal(err)
}
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N+N; n++ {
if err := validator.Validate(msg); err != nil {
b.Fatal(err)
}
_, err := proto.Marshal(msg)
if err != nil {
b.Fatal(err)
}
}
})
}
}
func BenchmarkOptimizedValidateAndMarshal(b *testing.B) {
cases := map[string]proto.Message{
"medium": createSampleProtoMessage(),
"large": createLargeProtoMessage(),
}
for hint, msg := range cases {
b.Run(hint, func(b *testing.B) {
val, err := protovalidate.New(
protovalidate.WithMessages(&schemav1.IdentifierEventOrder{}),
//protovalidate.WithDisableLazy(),
protovalidate.WithFailFast(),
)
if err != nil {
b.Fatal(err)
}
if err := val.Validate(msg); err != nil {
b.Fatal(err)
}
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N+N; n++ {
if err := val.Validate(msg); err != nil {
b.Fatal(err)
}
_, err := proto.Marshal(msg)
if err != nil {
b.Fatal(err)
}
}
})
}
}
cpu: Apple M1 Pro
BenchmarkJustMarshal/medium-10 2846248 375.1 ns/op 182 B/op 1 allocs/op
BenchmarkJustMarshal/large-10 1490960 803.4 ns/op 409 B/op 1 allocs/op
BenchmarkMarshalAndValidate/medium-10 94866 10813 ns/op 2245 B/op 84 allocs/op
BenchmarkMarshalAndValidate/large-10 55632 18842 ns/op 4192 B/op 138 allocs/op
BenchmarkOptimizedValidateAndMarshal/medium-10 108760 10050 ns/op 1996 B/op 78 allocs/op
BenchmarkOptimizedValidateAndMarshal/large-10 54223 18850 ns/op 4074 B/op 139 allocs/op
Hello Team,
I am raising this issue to get an idea of whether we should choose
protovalidate-goorprotoc-gen-validate. As reported in other issues, some performance penalty is expected:I am wondering what the target performance is. I ran a couple of benchmarks to estimate the effective memory utilization increase compared to our baseline. I have three scenarios:
370MB5800MB❗5500MB❗ (CEL alone accounts for3600MB)The payload used for measuring has approximately
50fields, nested in different configurations.I'm wondering what we can do on our end to adopt the library: