Description
What version of protobuf and what language are you using?
Version: v1.3.5 -> v1.4.2 golang
What did you do?
Updated dependency version (see https://github.com/istio/istio/pull/24689/files for exact PR)
What did you expect to see?
Performance improves or remains stable
What did you see instead?
Performance on marshalling Any types is ~2x slower
Running one of our benchmarks, which is protobuf encoding heavy, we see a huge regression:
$ benchstat /tmp/{old,pr}
name old time/op new time/op delta
ListenerGeneration/empty-6 2.82ms ± 0% 5.12ms ± 0% ~ (p=1.000 n=1+1)
ListenerGeneration/telemetry-6 3.75ms ± 0% 7.50ms ± 0% ~ (p=1.000 n=1+1)
ListenerGeneration/virtualservice-6 2.81ms ± 0% 5.12ms ± 0% ~ (p=1.000 n=1+1)
name old alloc/op new alloc/op delta
ListenerGeneration/empty-6 1.30MB ± 0% 1.43MB ± 0% ~ (p=1.000 n=1+1)
ListenerGeneration/telemetry-6 1.62MB ± 0% 1.82MB ± 0% ~ (p=1.000 n=1+1)
ListenerGeneration/virtualservice-6 1.30MB ± 0% 1.43MB ± 0% ~ (p=1.000 n=1+1)
name old allocs/op new allocs/op delta
ListenerGeneration/empty-6 19.0k ± 0% 25.5k ± 0% ~ (p=1.000 n=1+1)
ListenerGeneration/telemetry-6 24.4k ± 0% 34.7k ± 0% ~ (p=1.000 n=1+1)
ListenerGeneration/virtualservice-6 19.0k ± 0% 25.5k ± 0% ~ (p=1.000 n=1+1)
Looking at profiles, this can be narrowed down to proto.Marshal spending far more time than previously.
Benchmarks can be run from istio/istio with and without the update with go test ./pilot/pkg/proxy/envoy/v2 -run=^$ -bench='.*Generation' -benchmem
CPU profiles:
profile-updated.tar.gz
profile-old.tar.gz
By the way, these are not really "micro" benchmarks - this is our core functionality, so our entire application will run 2x slower with this update.