Live data from Hacker News

Cap’n Proto

capnproto.org

11–20 of 194 posts

Re: Cap’n Proto

#11
Hi all, Cap'n Proto author here. Thanks for the post.

Just wanted to note that although Cap'n Proto hasn't had a blog post or official release in a while, development is active as part of the Sandstorm project (https://sandstorm.io). Cap'n Proto -- including the RPC system -- is used extensively in Sandstorm. Sandboxed Sandstorm apps in fact do all their communications with the outside world through a single Cap'n Proto socket (but compatibility layers on top of this allow apps to expose an HTTP server).

Unfortunately I've fallen behind on doing official releases, in part because an official release means I need to test against Windows, Mac, and other "supported platforms", whereas Sandstorm only cares about Linux. Windows is especially problematic since MSVC's C++11 support is spotty (or was last I tried), so there's usually a lot of work to do to get it working.

As a result Sandstorm has been building against Cap'n Proto's master branch so that we can make changes as needed for Sandstorm.

I'm hoping to get some time in the next few months to go back and do a new release.

Re: Cap’n Proto

#12
post #9

Interfaces! Inheritance! Looks promising. Protocol buffers are nice for their compact encoding and multi-language generator support but as a schema language they are really cumbersome. Composition is pretty much all you get, there are no longer required fields, you can't even use enums as a key type in a map. I'm sure their use cases are not necessarily the same as mine but sometimes I miss just using plain old XML.

To be clear, Cap'n Proto's serialization layer, from a schema perspective, is almost exactly the same as Protobuf (though with a very different underlying encoding).

The interfaces and inheritance relate to the RPC system. The interfaces are for remote objects.

See: https://capnproto.org/rpc.html

Re: Cap’n Proto

#14
I've always liked Cap'n Proto because it was (quite literally) the ideas behind Protobuf taken to an extreme, or, depending on your point-of-view, reduced to its most basic components: data structures already have to sit in memory looking a certain way, why can't we just squirt that on the wire instead of some fancy bespoke type-length-value struct?

Of course, the hardest part is convincing everyone that it's not your bespoke type-length-value struct, but that you have good reasons for what you're doing. I think the humorous, not-so-self-serious presentation has worked in its favor (but that's just a subjective opinion and I can't back it up with data).

Re: Cap’n Proto

#15

Is it faster than MsgPack?

Depends on the use case! In fact, the answer to "is X format faster than Y format" always depends on the use case. It's always easy to construct cases where one or the other looks better. People of course want to know "on average", but in reality there's no such thing as an "average" use case. You'll ultimately have to test the case you have in mind to find out.

With that said, here are some considerations:

- msgpack is usually used as a binary encoding of JSON, with no schemas. That means that textual field names are included in the encoded message. Formats like Protobuf and Cap'n Proto that have schemas known in advance can avoid this bloat, making them faster and smaller.

- msgpack is not a zero-copy encoding. It's necessary to parse the whole message upfront before you can use it, like with protobuf. Cap'n Proto is zero-copy, the advantages of which are described extensively on the page. For example, if you have a multi-gigabyte file containing a massive Cap'n Proto message, and you just want to read one field from one place in that message, you can do that by memory-mapping the file. No need to read it all in. That's not possible with Protobuf or Msgpack.

I think it's best to focus on these kind of paradigm-shifts when trying to reason about performance. You can always micro-optimize the encoding path later on, but you can't suddenly switch to zero-copy later if your data format wasn't designed for it.

Re: Cap’n Proto

#16
post #8

Earlier quoted context omitted.

I had the exact same reaction. I really had to read for a long time (including code) before deciding it was real. "infinitely faster" confused me too.

Although this is listed on the introduction page, the author is also the same person that co-founded Sandstorm.io[1]. [1] https://sandstorm.io/about

Mmhmm.

Re: Cap’n Proto

#17
post #14

I've always liked Cap'n Proto because it was (quite literally) the ideas behind Protobuf taken to an extreme, or, depending on your point-of-view, reduced to its most basic components: data structures already have to sit in memory looking a certain way, why can't we just squirt that on the wire instead of some fancy bespoke type-length-value struct? Of course, the hardest part is convincing everyone that it's not you…

I thought that the main reason we didn't do this was because it's was hard - platform inconsistencies like 32/64 bit, endianness, not to mention differences between how languages store things, etc.

The thing that irks me about these methods is that if you're using a capnproto Int rather than a regular Int, doesn't that mean that you're basically forgoing a lot of functionality that was built around and works with the regular old data types?

For example, we also do that with numpy data types in python, but there the performance benefit is super clear - numerical operations dominate. I guess it really depends on your use case. If most of your time is spend on serde, then perhaps it's worth it.

Re: Cap’n Proto

#18
Correct me if I'm wrong, but some of this sounds like blitting, except optimized for the in-memory structure and not the on-disk structure.

In 2008, Joel Spolsky wrote about 1990s-era Excel file formats and how they used this technique to deal with how slow computers were then [1]. Same technique, new problem set.

[1] http://www.joelonsoftware.com/items/2008/02/19.html

Re: Cap’n Proto

#19

Is it faster than MsgPack?

Is X faster than Y will be tough to determine without a really detailed treatment of the use case. For example in C++ you want to account for the unavoidable construction of your class type, its inevitable destruction, how long it takes to put it on or take it off the wire, how often you might expect to miss the cache when referencing it, whether the type of movable or copyable and how expensive that is, whether or not you can reset it for reuse without destroying it, and much more. If you were to compare to protobufs I doubt that you'd find serialization and deserialization to be the predominant costs. I don't know what the cost breakdown looks like for capnproto, but maybe kentonv has standing benchmarks.

Re: Cap’n Proto

#20
post #14

I've always liked Cap'n Proto because it was (quite literally) the ideas behind Protobuf taken to an extreme, or, depending on your point-of-view, reduced to its most basic components: data structures already have to sit in memory looking a certain way, why can't we just squirt that on the wire instead of some fancy bespoke type-length-value struct? Of course, the hardest part is convincing everyone that it's not you…

I thought that the main reason we didn't do this was because it's was hard - platform inconsistencies like 32/64 bit, endianness, not to mention differences between how languages store things, etc. The thing that irks me about these methods is that if you're using a capnproto Int rather than a regular Int, doesn't that mean that you're basically forgoing a lot of functionality that was built around and works with the…

> platform inconsistencies like 32/64 bit,

In terms of data layout, 32-bit vs. 64-bit architecture only really affects pointer size. But Cap'n Proto does not encode native pointers (that obviously wouldn't work), so this turns out not to matter.

> endianness,

It turns out almost everything is little-endian now. Also, big-endian architectures almost always have efficient instructions for loading little-endian data. So Cap'n Proto just has to make sure to use those instructions in the getters/setters for integer fields.

> not to mention differences between how languages store things, etc.

Cap'n Proto actually doesn't attempt to match how any language stores things. Instead, it defines its own layout that is appropriate for modern CPUs. It ends up being very similar to the way many languages store things (especially C), but isn't intended to exactly match.

The C++ implementation of Cap'n Proto generates inline getter/setter methods that do pointer arithmetic that is equivalent to what the compiler would generate when accessing a struct.

For Java, Cap'n Proto data is stored in a ByteBuffer, which effectively allows something like pointer arithmetic. Again, getters/setters are generated which use the right offsets.

Most other languages end up looking like either C++ or Java.

Post reply on HN