Boost logo

Boost Users :

Subject: Re: [Boost-users] [Serialization] Speedding up client-servercommunication
From: Juraj Ivančić (juraj.ivancic_at_[hidden])
Date: 2010-02-05 21:18:44


Robert Ramey wrote:
> Juraj Ivancic wrote:

>> This could be improved further:
>>
>> 1)By replacing stringstreams with something more lightweight.
>
> In small experiments, I've found this to make a big difference. And
> it's not that hard as one needs only support a subset of the hole
> streambuf functionality.

I am not really a performance freak, but creating and destroying
archives and streams really turned out to be bottleneck so I came up
with this serialization technique. std::stream overhead never really
bothered me so I left it there to this day (with a todo on top of it
for some sunny day when there will be nothing else to do :) ).

> Note that "implementation level" is also important. The default
> is that the class id is looked up in a table to check to see if
> versioning must be supported. lowering the "implementation level"
> to "object serialization" (hmm I don't remember - better double
> check). Means that this class information is not checked. This
> speeds things up, but will mean that trying to load old archives
> could be a problem. For MPI type applications this shouldn't
> be a problem so it should also be considered.

Thanks for the reminder. I am a bit rusty about this particular piece of
coding. I wrote this about 2 years ago, and added myself a habit of
adding

BOOST_CLASS_IMPLEMENTATION(X, boost::serialization::object_serializable)
BOOST_CLASS_TRACKING (X, boost::serialization::track_never )

for every class used with this code, gradually forgetting its original
purpose. I do remember however that producing above two lines of code
did cause me quite a bit of headache and debugging sessions at the time.

The thing made me think I was doing something I was not supposed to was
this:

stringstream is;
IArchive ia( is );
Object object1;
Object object2;

ia << object1
sendData( is ); // sends version + object1 data
ia << object2;
sendData( is ) // sends only object2 data

On the other side of the network there were two deserializers:

stringstream os1;
stringstream os2;
OArchive o1( os1 );
OArchive o2( os2 );
Object object1;
Object object2;

os1 << receivedData( 1 ); // contains version + object1 data
o1 >> object1;
os2 << receivedData( 2 ); // contains only object2 data
o2 >> object2;

The problem was that version data was written only once per archive
and class and this caused problems when deserializing, as an exception
was thrown when object2 was deserialized as Oarchive o2 expected version
information on the stream.

So I started using object_serializable class implementation which
avoided versioning entirely, but I was left with a bitter taste in my
mouth that I was doing something inappropriate. I'm glad to hear this is
not the case although I do think it's a bit awkward. I'd really prefer
that archives did not possess 'this is the first object of this class'
knowledge as that leaves one wondering if they were ever intended to be
reused anyway.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net