protobuf icon indicating copy to clipboard operation
protobuf copied to clipboard

proto: specialize map<string, string> for performance

Open jmillikin-stripe opened this issue 6 years ago • 3 comments

Background: https://github.com/golang/protobuf/issues/624

Serialization of map fields currently hits a slow, reflection-based path. This is understandable for the general case (nested messages are hard), but there are some special cases where maps get used a lot and a fast path would be very valuable.

My specific use case is a map<string, string> used to represent arbitrary human-meaningful metadata in a distributed monitoring system (similar to Prometheus). Benchmarking shows that our tooling is spending a material amount of CPU time in the closures returned from proto.makeMapMarshaler.

jmillikin-stripe avatar Jan 08 '19 19:01 jmillikin-stripe

fwiw, I wrote a quick benchmark for comparing against gogo faster:

func BenchmarkMarshalSSFSpan(b *testing.B) {
    s := &ssf.SSFSpan{
        Tags: make(map[string]string),
    }
    for i := 0; i < 20; i++ {
        s.Tags[strconv.Itoa(i)] = strconv.Itoa(i * 1000)
    }

    b.ResetTimer()
    b.ReportAllocs()
    for i := 0; i < b.N; i++ {
        _, err := proto.Marshal(s)
        if err != nil {
            panic(err)
        }
    }
}

SSFSpan is from https://github.com/stripe/veneur/blob/master/ssf/sample.proto.

BenchmarkMarshalSSFSpan-4         100000         15003 ns/op        3952 B/op        165 allocs/op
BenchmarkMarshalSSFSpan-4         500000          2413 ns/op         240 B/op          1 allocs/op

Top is protoc-gen-go, bottom is protoc-gen-gogofaster.

bartle-stripe avatar Jan 19 '19 08:01 bartle-stripe

If nobody is working on this I would like to get assigned to this.

prannayk avatar Jan 24 '19 17:01 prannayk

Making a note that this should probably also handle map[string]*Message.

dsnet avatar Nov 17 '20 04:11 dsnet