$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: [boost] Problem with boost deserialization.
From: Esteban RG (stbnrivas_at_[hidden])
Date: 2010-11-09 14:30:32
Hi,
I need serialization in a project of mine. I have reduced my options to
boost and ProtocolBuffer, but in order to be able to decide which one to
use, I am trying to build a timing test for serialization and
deserialization. Let me explain a little about my setup:
a) Platform:
- windows 7, 64bit version
- visual studio 2008 express edition x32
b) Additional library:
- ACE library for High resolution timer.
The code (an explanations) that I have used to implement the comparison is
at follows:
I build a class with four different lists of boost/serialization/list like
documentation states:
std::list<unsigned int> &lint_;
std::list<ACE_INT64> &llong_;
std::list<float> &lfloat_;
std::list<std::string> &lstring_;
The test is increasing the size of every list simultaneously. Then it gets
serializated and deserializated and finally I get the time results for this
process.
However there is one issue: Serialization always works, but deserialization
fails during execution time whenever the lists are bigger than 10 elements,
throws a exception "input stream error" into
boost/serialization/throw_exception.hpp as seen with the debugger in the
variable/const std::exception const &e (boost library)
Visual studio shows this message: Unhandled exception at 0x765cb727 in
prTestBoostSerialization2.exe: Microsoft C++ exception:
boost::archive::archive_exception at memory location 0x003fc564..
my class definition is:
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/list.hpp>
//#include <boost/serialization/version.hpp>
//#include <boost/serialization/split_member.hpp>
#include <iostream>
#include <list>
#include <string>
class BoostSerializationClass {
public:
// Not required because al member are public
// friend class boost::serialization::access;
BoostSerializationClass(std::list<unsigned int> &lint
, std::list<float> &lfloat
, std::list<ACE_INT64> &llong
, std::list<std::string> &lstring)
: lint_(lint), lfloat_(lfloat), llong_(llong), lstring_(lstring) {
//std::cout << std::endl << " max size " << lint_.max_size();
//std::cout << std::endl << " " << llong_.max_size();
//std::cout << std::endl << " " << lfloat_.max_size();
//std::cout << std::endl << " " << lstring_.max_size();
}
std::list<unsigned int> &lint_;
std::list<ACE_INT64> &llong_;
std::list<float> &lfloat_;
std::list<std::string> &lstring_;
};
namespace boost {
namespace serialization {
template<class Archive>
void serialize(Archive &ar, BoostSerializationClass &c
, const unsigned int version){
ar & c.lint_;
ar & c.llong_;
ar & c.lfloat_;
ar & c.lstring_;
}
}
}
-----------------------
And main function is:
#include <iostream>
#include <fstream>
//#include <cstdlib>
#include <ace/OS.h>
#include <ace/Time_Value.h>
#include <ace/High_Res_Timer.h> // high resolution timer
// include for BOOST
#include "../prTestProtocolBuffers/BoostSerializationClass.h"
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
//#include <list> <- dont include this use boost/serialization/list
#include <boost/serialization/list.hpp>
void gen_random_string(std::string &s, const int len);
int ACE_TMAIN(int argc, ACE_TCHAR* argv[]){
//int lengthList = 5;
//int lengthList = 10;
int lengthList = 15;
//int lengthList = 50;
// int lengthList = 100;
// int lengthList = 1000;
std::list<unsigned int> listInteger,listInteger2;
std::list<float> listFloat,listFloat2;
std::list<ACE_INT64> listLongs,listLongs2;
std::list<std::string> listString,listString2;
int rint = 0;
float rfloat = 0.f;
ACE_INT64 rint64 = 0;
std::string rstring = "";
std::cout << std::endl << "Begin random generate message. Please be
patient.";
// Generate random fields for messages
for (int i=0 ; i<lengthList ; i++){
listInteger.push_back( rand() );
listFloat.push_back( (float)rand()/(float)RAND_MAX );
listLongs.push_back( rand()*rand()*rand() );
gen_random_string(rstring, lengthList);
listString.push_back( rstring );
}
// BOOST SERIALIZATION
ACE_High_Res_Timer hrTimerBoost;
// Load fields into BoostSerializableClass
BoostSerializationClass boostSerializationClass( listInteger, listFloat,
listLongs, listString);
std::ofstream obfile("boost-file.bin");
boost::archive::binary_oarchive oba(obfile);
//ACE_Time_Value btvStart = ACE_OS::gettimeofday();
hrTimerBoost.start();
oba & boostSerializationClass; // boost serialization;
obfile.close();
hrTimerBoost.stop();
ACE_hrtime_t usecsBoost;
hrTimerBoost.elapsed_microseconds(usecsBoost);
//ACE_Time_Value btvEnd = ACE_OS::gettimeofday();
//ACE_Time_Value tvIncBoost( btvEnd.sec() - btvStart.sec() , btvEnd.msec() -
btvStart.msec() );
std::cout << std:: endl << " ===== BOOST SERIALIZATION =====" ;
//std::cout << std::endl << tvIncBoost.sec() << " seconds " <<
tvIncBoost.msec() << " mseconds" << std::endl ;
std::cout << std::endl << usecsBoost << " micro seconds " << std::endl ;
// BOOST DESERIALIZACION
BoostSerializationClass boostSerializationClass2( listInteger2, listFloat2,
listLongs2, listString2);
std::ifstream ibfile("boost-file.bin");
boost::archive::binary_iarchive iba(ibfile);
//btvStart = ACE_OS::gettimeofday();
hrTimerBoost.reset();
hrTimerBoost.start();
iba & boostSerializationClass2;
ibfile.close();
hrTimerBoost.stop();
hrTimerBoost.elapsed_microseconds(usecsBoost);
//btvEnd = ACE_OS::gettimeofday();
//tvIncBoost = ACE_Time_Value( btvEnd.sec() - btvStart.sec() , btvEnd.msec()
- btvStart.msec() );
std::cout << std:: endl << " ===== BOOST DE-SERIALIZATION =====" ;
//std::cout << std::endl << tvIncBoost.sec() << " seconds " <<
tvIncBoost.msec() << " mseconds" << std::endl ;
std::cout << std::endl << usecsBoost << " micro seconds " << std::endl ;
ACE_OS::system("pause");
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void gen_random_string(std::string &s, const int len) {
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
s.clear();
for (int i = 0; i < len ; ++i) {
s.push_back(rand() % (sizeof(alphanum) - 1) );
}
}
Can anyone of you help me with this? Any help would be truly appreciated.
Thanks in advance.