Live data from Hacker News

Hyperpb: Faster dynamic Protobuf parsing

buf.build

11–20 of 21 posts

Re: Hyperpb: Faster dynamic Protobuf parsing

#11
post #9

Earlier quoted context omitted.

Even before Hyperpb, Go was already very competitive, e.g. this article from last year: https://www.greptime.com/blogs/2024-04-09-rust-protobuf-perf...

My experience is that the practical performance achievable with Go is higher because the C++ lifetime issues are too difficult to reason about and therefore the developer is forced to copy for safety. In Go you can fairly easily alias everything from the physical buffer into your parsed object. In the official C++ library, protobuf refuses to acknowledge even the possibility of aliasing. Even if you say that your str…

Oh it’s worse, it’s a full on marshal of the whole data. What we need is a no-allocation-protobuf that binds to existing memory, knows about aliases, can deal with a pointer. I love protobuf but I’ve moved to other messaging implementations that provide a faster marshal/unmarshal. Maybe I’ll give this a try.

Re: Hyperpb: Faster dynamic Protobuf parsing

#12
post #9

Earlier quoted context omitted.

My experience is that the practical performance achievable with Go is higher because the C++ lifetime issues are too difficult to reason about and therefore the developer is forced to copy for safety. In Go you can fairly easily alias everything from the physical buffer into your parsed object. In the official C++ library, protobuf refuses to acknowledge even the possibility of aliasing. Even if you say that your str…

Oh it’s worse, it’s a full on marshal of the whole data. What we need is a no-allocation-protobuf that binds to existing memory, knows about aliases, can deal with a pointer. I love protobuf but I’ve moved to other messaging implementations that provide a faster marshal/unmarshal. Maybe I’ll give this a try.

Flatbuffers from Google is 11 years old and does that. (Protobufs is over 20 at this point).

https://stackoverflow.com/questions/25356551/whats-the-diffe...

Re: Hyperpb: Faster dynamic Protobuf parsing

#13
post #9

Earlier quoted context omitted.

My experience is that the practical performance achievable with Go is higher because the C++ lifetime issues are too difficult to reason about and therefore the developer is forced to copy for safety. In Go you can fairly easily alias everything from the physical buffer into your parsed object. In the official C++ library, protobuf refuses to acknowledge even the possibility of aliasing. Even if you say that your str…

Oh it’s worse, it’s a full on marshal of the whole data. What we need is a no-allocation-protobuf that binds to existing memory, knows about aliases, can deal with a pointer. I love protobuf but I’ve moved to other messaging implementations that provide a faster marshal/unmarshal. Maybe I’ll give this a try.

It's not out-of-the-box compatible with everything in the way that `proto3` is, but if dealing with the really atrocious performance and ergonomics of protobuf in C++ (among other targets) is bad enough to warrant going slightly off the beaten path, flatbuffers is still pretty mainstream. It's got bindings for the big languages and it's used IIRC in a bunch of the FAANG mobile clients, stuff like that.

Going a little further afield, `capnp` is cool. It's got a much nicer IDL and object model, but you start to get into where non-C++ bindings are "community maintained" in a pretty loose sense. I'm not sure how much sense it makes unless it really lands on your polyglot stack perfectly, because if you only need C++, zpp_bits is really ergonomic and approaches theoretical limits on performance along a number of dimensions.

I don't love any of the answers here.

Re: Hyperpb: Faster dynamic Protobuf parsing

#14

Interesting approach using a JIT compiler. It says compilation is slow, is there a way to persist the compiled code and load it later (for example for CLIs or faster redeployments)?

It's called AoT....

No, I think they want Profile-Guided Optimization. I think the C# AoT mode uses the results of a JIT first run.

Re: Hyperpb: Faster dynamic Protobuf parsing

#15
post #12

Earlier quoted context omitted.

Oh it’s worse, it’s a full on marshal of the whole data. What we need is a no-allocation-protobuf that binds to existing memory, knows about aliases, can deal with a pointer. I love protobuf but I’ve moved to other messaging implementations that provide a faster marshal/unmarshal. Maybe I’ll give this a try.

Flatbuffers from Google is 11 years old and does that. (Protobufs is over 20 at this point). https://stackoverflow.com/questions/25356551/whats-the-diffe...

MessagePack is what I’m currently using, I needed a small binary format.

Re: Hyperpb: Faster dynamic Protobuf parsing

#16

Earlier quoted context omitted.

Oh it’s worse, it’s a full on marshal of the whole data. What we need is a no-allocation-protobuf that binds to existing memory, knows about aliases, can deal with a pointer. I love protobuf but I’ve moved to other messaging implementations that provide a faster marshal/unmarshal. Maybe I’ll give this a try.

It's not out-of-the-box compatible with everything in the way that `proto3` is, but if dealing with the really atrocious performance and ergonomics of protobuf in C++ (among other targets) is bad enough to warrant going slightly off the beaten path, flatbuffers is still pretty mainstream. It's got bindings for the big languages and it's used IIRC in a bunch of the FAANG mobile clients, stuff like that. Going a little…

I’m currently using MessagePack. It does the job of making small binary messages but I still suffer from marshal/unmarshal copying.

For certain messages with a fixed size (no strings or arrays) I can pin a message and reuse its memory address within the queue but there’s still data in memory that needs to be copied. At the very least from the TCP/IP stack.

Re: Hyperpb: Faster dynamic Protobuf parsing

#17
post #4

See also the discussion on the technical description last week: https://news.ycombinator.com/item?id=44591605 (IMO much more interesting article than this announcement, and that probably should have gotten more attention than it did.)

Thanks! That one was recent enough that I think we can re-up it. I'll put a link to this thread in there, so people can read both.

Re: Hyperpb: Faster dynamic Protobuf parsing

#18
post #9

Earlier quoted context omitted.

Even before Hyperpb, Go was already very competitive, e.g. this article from last year: https://www.greptime.com/blogs/2024-04-09-rust-protobuf-perf...

My experience is that the practical performance achievable with Go is higher because the C++ lifetime issues are too difficult to reason about and therefore the developer is forced to copy for safety. In Go you can fairly easily alias everything from the physical buffer into your parsed object. In the official C++ library, protobuf refuses to acknowledge even the possibility of aliasing. Even if you say that your str…

I think you can alias the input data using Cord fields? As long as the input is Cord.

Re: Hyperpb: Faster dynamic Protobuf parsing

#19
post #9

Earlier quoted context omitted.

My experience is that the practical performance achievable with Go is higher because the C++ lifetime issues are too difficult to reason about and therefore the developer is forced to copy for safety. In Go you can fairly easily alias everything from the physical buffer into your parsed object. In the official C++ library, protobuf refuses to acknowledge even the possibility of aliasing. Even if you say that your str…

I think you can alias the input data using Cord fields? As long as the input is Cord.

Almost, but there aren't repeated cords yet. At my company we maintain a patch that adds repeated cords, but it's a real chore because the project changes a lot of little internal details as needed.

Re: Hyperpb: Faster dynamic Protobuf parsing

#20

Interesting approach using a JIT compiler. It says compilation is slow, is there a way to persist the compiled code and load it later (for example for CLIs or faster redeployments)?

It's called AoT....

The key feature seems to be the dynamic nature while still being fast. Sure, they could also build it as a compiler that does all mentioned in the article and then dump optimized Go code. Maybe even use the Go PGO instead of their own. But this is another approach, what I mean is caching of the JIT generated code to avoid doing expensive part again while still being dynamic and adapt to incoming messages.
Post reply on HN