Isn't that kind of custom interchange format what they're complaining about when they say that remote stores just push the complexity to the client?
I don’t know many sane people who want to use the kv store as a system of record, and even the people who expect it to be exhaustive (all possible keys) make me doubt their sanity for that and other reasons.
So far, everyone has a bit of code that looks for a key and, if it is missing, performs the work necessary to build the payload. The code that creates the payload is never more than a couple function calls away from the retrieval code.
Is this not exactly the behavior you'd see if you used UUIDs as your keys? Asking honestly.
In the case of Google's own Flatbuffers, the layout is going to be far more performant.
bytes key = 1;
bytes value = 2;
... your overhead can be as little as 4 bytes and you can alias the memory of the key and value (using a type like std::string_view) instead of copying it. It takes a few nanoseconds to decode a message like this.Do you have a source on that? Genuinely curious.
I don't know if I'd say Protobuf has "awful" performance. It's certainly much better that text-based formats like JSON. But the format is rather branch-y. You have to process it byte-by-byte, because e.g. integers are encoded in a variable-width encoding where each byte contains 7 bits of data plus 1 bit to indicate if this is the last byte. This results in a compact encoding, but takes a lot of cycles to encode and decode. Moreover, since everything is variable-width, in order to find any one field of the message, you must scan through all previous fields, parsing them one by one.
Cap'n Proto, FlatBuffers, and SBE all use "zero-copy" encodings, meaning the data is laid out on the wire in a format that is easy for a CPU to use directly. This means, for example, that integers are fixed-width, and fields are located at fixed offsets. This is must faster to parse (or even use in-place without parsing at all), but does result in somewhat larger encodings. (But then, you can always layer on independent compression when bandwidth matters more than CPU.)
My understanding is that Thrift is closer to Protobuf and contemporaneous with it, so I don't know why GP included it the list.
This is the hot path in C++[1]. A really large amount of work has gone into protobuf C++ performance in the last 3 years or so.
1: https://github.com/protocolbuffers/protobuf/blob/master/src/...
Yes, I suppose the branches in Protobuf can be pretty predictable. Still, you do generally have to examine each byte individually.
I think most serialization frameworks are likely to be overkill for such a use case, spending more time on setup than actual parsing.
Also note that storing the value (and maybe the key) with proper alignment might make it easier to use the data in-place, saving a copy.
However, if your entire world consists of pushing around images to GPUs/TPUs, that's pretty much the only workload you ever need to optimize from your larger ops system.
Edit: not sure that this particular use case is exactly what's going on in that benchmark, now that I look more closely. Also, I wouldn't want to assert that it's a use case that matters a ton.
https://github.com/nothings/stb/blob/master/stb_image.h#L120