GPB on non-Linux, non-Windows OS?

51 views
Skip to first unread message

Tim

unread,
Feb 26, 2009, 8:27:10 PM2/26/09
to Protocol Buffers
Anyone out there using GPB on an OS other than Linux or Windows? I've
been evaluating GPB for use in an embedded OS and at the moment am a
bit stuck between protobuf and protobuf-c. We would be using GPB for
simple data storage and serialization, and don't need RPC or even
Reflection. I checked out protobuf-c (0.7 is easiest to port, bc it's
before RPC was added) and this is definitely at the opposite end of
the spectrum. We would need to add quite a bit of functionality to it.

Kenton Varda

unread,
Feb 26, 2009, 8:41:57 PM2/26/09
to Tim, Protocol Buffers
I've tested in on OSX, FreeBSD, and Solaris, but those are not terribly different from Linux.  The Google implementations of protobufs definitely weren't designed for embedded systems, but there might be a case for taking the Google C++ implementation and ripping out all the "advanced" features to make something extremely stripped-down.

Tim

unread,
Feb 27, 2009, 1:58:59 PM2/27/09
to Protocol Buffers
That's precisely the case I've been hoping to make in my current work.
Since it's a static library to us, the point of stripping down isn't
so much for reduced footprint (our linker should eliminate the unused
modules anyway), but instead to simplify the porting effort.

One of the first things I did was to get libprotobuf 2.0.3 to "build"
in our environment (Freescale Codewarrior for PPC). But I did this in
a very incomplete way - just pulling in the missing headers from
Cygwin - hoping to get a feel for what the problem areas were. These
were the missing headers:

include/
_ansi.h
fcntl.h
newlib.h
machine/
_types.h
ieeefp.h
types.h
sys/
_types.h
config.h
fcntl.h
features.h
lock.h
stat.h
types.h
unistd.h

We would of course have to port most of the dependencies to our OS.
But some of these dependencies are things our system may never
support. For example, we don't currently support files and streams, or
exceptions. Our application really only needs the data object
serialization functionality, and the buffer/string interface is
sufficient. I thought that, like protobuf-c, there might there a past
release that would be a better starting point for stripping down
libprotobuf. But from what I can tell, it looks like even the initial
release supports files and streams. Pretty basic stuff in most
environments. I realize we are an exception here.

After briefly evaluating protobuf and protobuf-c, I can see that we
would have to heavily modify either one to achieve our goal. Given
this, I would like to lean towards stripping/modifying the c++
version, since our app is largely in c++ and this language might
facilitate our design modifications/extensions. Might you have any
recommendations or comments on an approach for stripping protobuf of
file and stream support?

Given our simple requirements and the perceived work involved with
stripping libprotobuf, however, my instinct tells me that protobuf-
c-0.7 would be a better starting point. It already is "stripped". I'm
guessing we could add the functionality we need there quicker than we
could strip down from protobuf. Maybe even rewrite it in c++. It's
only 3 files!

Comments, anyone?


On Feb 26, 5:41 pm, Kenton Varda <ken...@google.com> wrote:
> I've tested in on OSX, FreeBSD, and Solaris, but those are not terribly
> different from Linux.  The Google implementations of protobufs definitely
> weren't designed for embedded systems, but there might be a case for taking
> the Google C++ implementation and ripping out all the "advanced" features to
> make something extremely stripped-down.
>

Kenton Varda

unread,
Feb 27, 2009, 2:51:04 PM2/27/09
to Tim, Protocol Buffers
Stripping out the use of file descriptors and iostreams should be easy.  All you have to do is remove the relevant classes from zero_copy_stream_impl.{h,cc} and the corresponding methods from message.{h,cc}.  The rest of the library doesn't depend on these.  Note that protoc needs them, but presumably you will only run protoc on your build machines, not on the target platform itself.

I had an idea yesterday:  We could define a new superclass of protobuf::Message called protobuf::LeanMessage.  It would only have basic serialization methods -- no descriptors or reflection.  It could then live in a separate libprotobuf-lean library that contains only the I/O stuff and the LeanMessage interface.  Then we could add an option to protoc which outputs code that only implements this new "lean" interface.  Hopefully this new library would be far smaller than the current 870k libprotobuf.so.

Tim

unread,
Feb 27, 2009, 4:55:06 PM2/27/09
to Protocol Buffers
That sounds like an excellent idea!

On Feb 27, 11:51 am, Kenton Varda <ken...@google.com> wrote:
> Stripping out the use of file descriptors and iostreams should be easy.  All
> you have to do is remove the relevant classes from
> zero_copy_stream_impl.{h,cc} and the corresponding methods from
> message.{h,cc}.  The rest of the library doesn't depend on these.  Note that
> protoc needs them, but presumably you will only run protoc on your build
> machines, not on the target platform itself.
> I had an idea yesterday:  We could define a new superclass of
> protobuf::Message called protobuf::LeanMessage.  It would only have basic
> serialization methods -- no descriptors or reflection.  It could then live
> in a separate libprotobuf-lean library that contains only the I/O stuff and
> the LeanMessage interface.  Then we could add an option to protoc which
> outputs code that only implements this new "lean" interface.  Hopefully this
> new library would be far smaller than the current 870k libprotobuf.so.
>

Joshua Haberman

unread,
Mar 1, 2009, 5:12:05 PM3/1/09
to Protocol Buffers
Stripping down protobufs to their essence is *exactly* what I am doing
with pbstream:

http://github.com/haberman/pbstream

If you can hang tight for just another few weeks, I think you're going
to like what you see. The streaming decoder is more or less finished:
it's just over 500 lines of C99 and compiles to a ~6k object file.
I'm working now on an in-memory representation, which should be also
quite small. And while I don't have any benchmarks yet, I think it's
going to be extremely fast, despite not doing any code generation. In
the case where you're not actually copying the data into a separate
structure (eg. pure streaming) I think it will likely beat the main
implementation (malloc is more expensive than people realize).

Josh

Kenton Varda

unread,
Mar 1, 2009, 6:24:29 PM3/1/09
to Joshua Haberman, Protocol Buffers
On Sun, Mar 1, 2009 at 2:12 PM, Joshua Haberman <jhab...@gmail.com> wrote:

Stripping down protobufs to their essence is *exactly* what I am doing
with pbstream:

http://github.com/haberman/pbstream

If you can hang tight for just another few weeks, I think you're going
to like what you see.  The streaming decoder is more or less finished:
it's just over 500 lines of C99 and compiles to a ~6k object file.
I'm working now on an in-memory representation, which should be also
quite small.  And while I don't have any benchmarks yet, I think it's
going to be extremely fast, despite not doing any code generation.  In
the case where you're not actually copying the data into a separate
structure (eg. pure streaming) I think it will likely beat the main
implementation (malloc is more expensive than people realize).

Note that the C++ implementation only mallocs the *first* time you use an object.  If you reuse an object, it will reuse memory, only allocating new memory for parts of the message that weren't used before.  In practice, most performance-critical software reuses protobuf objects, so it's only fair to compare your implementation against this case.

Be careful about claiming that your code will be faster before actually running benchmarks.  I've been burned many times doing that.  :)
 

Joshua Haberman

unread,
Mar 1, 2009, 6:42:57 PM3/1/09
to Kenton Varda, Protocol Buffers
On Sun, Mar 1, 2009 at 3:24 PM, Kenton Varda <ken...@google.com> wrote:
On Sun, Mar 1, 2009 at 2:12 PM, Joshua Haberman <jhab...@gmail.com> wrote:

Stripping down protobufs to their essence is *exactly* what I am doing
with pbstream:

http://github.com/haberman/pbstream

If you can hang tight for just another few weeks, I think you're going
to like what you see.  The streaming decoder is more or less finished:
it's just over 500 lines of C99 and compiles to a ~6k object file.
I'm working now on an in-memory representation, which should be also
quite small.  And while I don't have any benchmarks yet, I think it's
going to be extremely fast, despite not doing any code generation.  In
the case where you're not actually copying the data into a separate
structure (eg. pure streaming) I think it will likely beat the main
implementation (malloc is more expensive than people realize).

Note that the C++ implementation only mallocs the *first* time you use an object.  If you reuse an object, it will reuse memory, only allocating new memory for parts of the message that weren't used before.

What about strings and repeated elements?  String assignment will at least sometimes call malloc() to re-allocate the string, though I don't know enough about STL to know how often this happens.  And string assignment will always copy the data at least, whereas with pbstream that data is never copied unless the client decides it wants to store it.
 
  In practice, most performance-critical software reuses protobuf objects, so it's only fair to compare your implementation against this case.

As long as you think it's fair.  :)
 

Be careful about claiming that your code will be faster before actually running benchmarks.  I've been burned many times doing that.  :)

I said "likely."  :)  I probably am a bit overconfident, because last time I told someone that I'd beat their data-streaming tool by 20x by not calling malloc() in the critical path, I hit 20x almost spot-on.  proto2 is a lot more optimized than that application was, but I definitely think that never calling malloc() in the critical path, as well as never copying string data, will likely yield compelling performance.

It would be nice if there was an open-source benchmark suite that would make it easier to compare performance across implementations.

Josh

Kenton Varda

unread,
Mar 1, 2009, 9:56:09 PM3/1/09
to Joshua Haberman, Jon Skeet, Protocol Buffers
On Sun, Mar 1, 2009 at 3:42 PM, Joshua Haberman <jhab...@gmail.com> wrote:
What about strings and repeated elements?  String assignment will at least sometimes call malloc() to re-allocate the string, though I don't know enough about STL to know how often this happens.  And string assignment will always copy the data at least, whereas with pbstream that data is never copied unless the client decides it wants to store it.

I believe GCC's std::string will only malloc if it needs to grow, so on reuse there should be no new allocation.

Avoiding copying string data could help, though.
 
It would be nice if there was an open-source benchmark suite that would make it easier to compare performance across implementations.

I believe Jon Skeet was working on that.  Jon, any progress?

Kenton Varda

unread,
Mar 1, 2009, 9:56:39 PM3/1/09
to Joshua Haberman, Jon Skeet, Protocol Buffers
On Sun, Mar 1, 2009 at 6:56 PM, Kenton Varda <ken...@google.com> wrote:
I believe GCC's std::string will only malloc if it needs to grow, so on reuse there should be no new allocation.

I meant, reuse to store a string of the same or lesser size, of course.

Jon Skeet

unread,
Mar 2, 2009, 6:43:08 AM3/2/09
to Kenton Varda, Joshua Haberman, Protocol Buffers
2009/3/2 Kenton Varda <ken...@google.com>
It would be nice if there was an open-source benchmark suite that would make it easier to compare performance across implementations.

I believe Jon Skeet was working on that.  Jon, any progress?

The relevant data is all available under

http://github.com/jskeet/dotnet-protobufs/tree/master

Relevant files:
protos/google/benchmark.proto and protos/google/benchmark_speed.proto - protobuffer description files
testdata/benchmark_message1.dat and testdata/benchmark_message3.dat - sample binary data
src/ProtoBench/Program.cs - code to execute benchmarks against arbitrary messages
http://code.google.com/p/protobuf-csharp-port/wiki/ProtoBench - a little bit of documentation

I've ported the code to Java, but haven't sent it to Kenton yet. I don't know exactly where we'd want to put it in the main distribution. Kenton, how do you want to proceed with this?

Obviously it would be nice to see the same metrics ported to lots of implementations. If there are other metrics which would be useful, they should be easy to integrate.

Jon

Tim

unread,
Mar 2, 2009, 12:19:05 PM3/2/09
to Protocol Buffers
I'm interested in your work, Josh. But I'm having trouble
understanding what your goal is. I.e. what is the essence of protobufs
that you are trying to distill? And how would you differentiate your
work from Dave's protobuf-c project? And is your implementation going
to be entirely in C?

Tim

Kenton Varda

unread,
Mar 2, 2009, 1:11:19 PM3/2/09
to Jon Skeet, Joshua Haberman, Protocol Buffers
On Mon, Mar 2, 2009 at 3:43 AM, Jon Skeet <sk...@pobox.com> wrote:
I've ported the code to Java, but haven't sent it to Kenton yet. I don't know exactly where we'd want to put it in the main distribution. Kenton, how do you want to proceed with this?

A top-level "benchmark" directory seems like it would make sense, like the "examples" directory with a Makefile that covers all languages.
Reply all
Reply to author
Forward
0 new messages