Hacker News new | ask | show | jobs
by sneak 1917 days ago
One thing that people seem to gloss over when comparing these is that you also need to compare the serialization. gRPC using protobuf means you get actual typed data, whereas typing in JSON (used by the other two) is a mess (usually worked around by jamming anything ambiguous-in-javascript like floats, dates, times, et c into strings).

If you're using typed languages on either the client or the server, having a serialization system that preserves those types is a very nice thing indeed.

1 comments

> usually worked around by jamming anything ambiguous like floats, dates, times, et c into strings

because nobody has ever done this with protobuf...

btw what is the protobuf standard type for "date"?

That would be a Timestamp, found in the "well-known types" [0]. You can use your own encoding (milliseconds since epoch, RFC3339 string, etc), but using Timestamp gets you some auto-generated encoding / decoding functions in the supported languages.

[0] https://developers.google.com/protocol-buffers/docs/referenc...

A timestamp is not quite the same thing as a calendar date.
Timestamp is fundamentally flawed and should only be used in applications without any kind of performance/efficiency concerns, or for people who really need a range of ten thousand years. The problem with Timestamp is it should not have used variable-length integers for its fields. The fractional part of a point in time is uniformly distributed, so most timestamps are going to have either 4 or 5 bytes in their representation, meaning int32 is worse than fixed32 on average. The whole part of an epoch offset in seconds is also pretty large, it takes 5 bytes to represent the present time. Since you also have two field tags, Timestamp requires 11-12 bytes to represent the current time, and it's expensive to decode because it takes the slowest-possible path through the varint decoder.

Reasonable people can used a fixed64 field representing nanoseconds since the unix epoch, which will be very fast, takes 9 bytes including the field tag, and yields a range of 584 years which isn't bad at all.

int64 representing unix epoch millis (in UTC) is what I usually use. You need to jump through an additional hoop to store timezone or offset.

You can, of course, do the thing that JS requires you always do and put an ISO8601 date in a string. This has the benefit of storing the offset data in the same field/var.

Javascript needs int64s as strings, I believe, because the JS int type maxes out at 53 bits.