Faster Protocol Buffers (2019)
blog.najaryan.net
blog.najaryan.net
We used to store 20-30mb of animation data with it and we'd just mmap the whole file and let the kernel handle paging it in/out, worked great.
I don't know how up to date their benchmarks[2] are but my experience has been that it beats almost every other off-the-shelf solution(other than maybe capn-proto which has some similar properties).
[1] https://google.github.io/flatbuffers/
[2] https://google.github.io/flatbuffers/flatbuffers_benchmarks....
But the main reason people use protobuf is it is compact, which this table does accurately show. Flatbuffers are always larger.
From what I recall in the message format[1] protocol buffers require you to walk quite a few parts of the data structures where in flatbuffers you are just reading offset and traversal is significantly faster.
Flatbuffers also let's you control data layout into the packed buffer so you can guarantee cache locality which makes a huge difference when it comes to real-world traversal performance. Data oriented design and FlatBuffers go together really well(which isn't a surprise given some of the background of where FlatBuffers comes from).
[1] https://developers.google.com/protocol-buffers/docs/encoding...
If you are interested in the topic you may be also interested in a research library I wrote recently: https://github.com/splunk/exp-lazyproto, which among other things exploits the partial (de)serialization technique. This is just a prototype for now, one day I may actually do a production quality implementation.
message Metric {
// MetricDescriptor metric_descriptor = 1;
// Resource resource = 2;
repeated Int64TimeSeries int64_timeseries = 3;
}
When then message is deserialised, those will be placed in a separate binary buffer, which is used directly when reserialising. It even works for other types of field. Originally this functionality was lost in the transition from proto2 to proto3 but was added back a long time ago now.This feels like a cleaner solution to me as it's what this feature is really intended for.
[1] https://developers.google.com/protocol-buffers/docs/proto3#u...
[2] https://developers.google.com/protocol-buffers/docs/referenc...
The issue is the agent/collector is stateless and agnostic about where the data eventually goes. It's not the final destination, just an API router / transformer.
An extension to OTLP that uses shared state (and columnar encoding) to achieve more compact representation and is suitable for the last network leg in the data delivery path has been proposed and may become a reality in the future: https://github.com/open-telemetry/oteps/pull/171
That’s because the protocol overheads cause “write multiplication” of a hundred-to-one or worse. Every byte of metric ends up nearly a kilobyte on the wire.
Meanwhile I did some experiments that showed that even with a tiny bit of crude data-oriented design and delta compression a single box could collect 10K metrics across 10K endpoints every second without breaking a sweat.
The modern REST / RPC approach is fine for business apps but is an unmitigated disaster for collecting tiny metrics.
Set your goals higher than collecting a selected subset of 1% of the available metrics 60x less frequently than admins would like…