|
Boost Users : |
Subject: Re: [Boost-users] [serialization] Runtime overhead of serialization archives
From: Georg Gast (georg_at_[hidden])
Date: 2016-09-25 04:38:20
Am 25.09.2016 um 07:05 schrieb Ernest Zaslavsky:
> I guess you are still comparing release to debug version. I've ran your code and this is what I've got
>
> Win7 x64, VS2015 Update3, Release, x64
>
> Run on (8 X 3392 MHz CPU s)
> 09/25/16 07:36:53
> Benchmark Time CPU Iterations
> ------------------------------------------------------------
> to_wire_xml/8 39564 ns 39980 ns 17949 195.409kB/s
> to_wire_xml/64 98915 ns 98035 ns 7479 637.527kB/s
> to_wire_xml/512 583376 ns 583961 ns 1122 856.222kB/s
> to_wire_xml/4k 4494721 ns 4428415 ns 155 903.258kB/s
> to_wire_xml/32k 35621888 ns 35100225 ns 20 911.675kB/s
> to_wire_xml/256k 285296564 ns 280801800 ns 2 911.675kB/s
> to_wire_xml/2M 2294702350 ns 2293214700 ns 1 893.069kB/s
> to_wire_xml/4M 4596100456 ns 4586429400 ns 1 893.069kB/s
> from_wire_xml/8 44701 ns 44361 ns 15473 176.11kB/s
> from_wire_xml/64 97779 ns 98035 ns 7479 637.527kB/s
> from_wire_xml/512 523956 ns 530403 ns 1000 942.679kB/s
> from_wire_xml/4k 3919513 ns 3877482 ns 173 1031.6kB/s
> from_wire_xml/32k 30990532 ns 31200200 ns 22 1025.63kB/s
> from_wire_xml/256k 248254367 ns 249601600 ns 3 1025.63kB/s
> from_wire_xml/2M 1990579271 ns 1981212700 ns 1 1033.71kB/s
> from_wire_xml/8M 7927240207 ns 7924850800 ns 1 1033.71kB/s
> to_wire_text/8 13381 ns 13142 ns 49857 594.483kB/s
> to_wire_text/64 31969 ns 31985 ns 22436 1.90827MB/s
> to_wire_text/512 180335 ns 179751 ns 4079 2.71643MB/s
> to_wire_text/4k 1363654 ns 1375560 ns 499 2.83975MB/s
> to_wire_text/32k 10990438 ns 10968820 ns 64 2.84898MB/s
> to_wire_text/256k 86883137 ns 88400567 ns 9 2.82804MB/s
> to_wire_text/2M 696132001 ns 686404400 ns 1 2.91373MB/s
> to_wire_text/4M 1398212634 ns 1388408900 ns 1 2.881MB/s
> from_wire_text/8 11158 ns 11195 ns 64102 697.873kB/s
> from_wire_text/64 25274 ns 25588 ns 28045 2.38534MB/s
> from_wire_text/512 138245 ns 137666 ns 4986 3.54685MB/s
> from_wire_text/4k 1047166 ns 1046497 ns 641 3.73269MB/s
> from_wire_text/32k 8304279 ns 8320053 ns 90 3.75599MB/s
> from_wire_text/256k 66510527 ns 66654973 ns 11 3.75066MB/s
> from_wire_text/2M 533393808 ns 530403400 ns 1 3.77071MB/s
> from_wire_text/4M 1055956857 ns 1060806800 ns 1 3.77071MB/s
> to_wire_binary/8 5444 ns 5460 ns 100000 1.39732MB/s
> to_wire_binary/64 5411 ns 5424 ns 112179 11.2538MB/s
> to_wire_binary/512 5523 ns 5563 ns 112179 87.7797MB/s
> to_wire_binary/4k 5966 ns 5980 ns 112179 653.244MB/s
> to_wire_binary/32k 28940 ns 29412 ns 24929 1062.5MB/s
> to_wire_binary/256k 251626 ns 250358 ns 2804 998.569MB/s
> to_wire_binary/2M 2548630 ns 2540925 ns 264 787.115MB/s
> to_wire_binary/4M 6361041 ns 6407184 ns 112 624.299MB/s
> from_wire_binary/8 5363 ns 5284 ns 112179 1.44375MB/s
> from_wire_binary/64 5371 ns 5460 ns 100000 11.1785MB/s
> from_wire_binary/512 5386 ns 5460 ns 100000 89.4282MB/s
> from_wire_binary/4k 5483 ns 5424 ns 112179 720.244MB/s
> from_wire_binary/32k 7685 ns 7649 ns 89743 3.98998GB/s
> from_wire_binary/256k 25332 ns 25588 ns 28045 9.54136GB/s
> from_wire_binary/2M 620654 ns 625672 ns 1122 3.12164GB/s
> from_wire_binary/4M 1306333 ns 1306960 ns 561 2.98881GB/s
>
Dear Earnest,
Thanks for running my code :)
have you run my code from the post at 23.9.16 19:41 (make_array)?
In your result the XML settles at about 2.9 MB/sec (from wire) and the
text archive at about 3.8 MB/sec (from wire).
My guess from this values is, that you testes the version with
make_array in the serialization functions. I realized this DEBUG thing
too and i fixed it in the meantime. On my desktop workstation
The make_binary_object improved the performance a lot.
Here is the current version of the source from my homepage
Georg
<code>
// STL Archive + Stuff
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/unique_ptr.hpp>
// include headers that implement a archives in xml/text/binary format
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
// IO stream for the to/from wire functions
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/stream.hpp>
#include <memory>
#include <cstdint>
#include <vector>
#include <benchmark/benchmark.h>
// the step interval for the benchmarks
static const int range_mult = 4;
static const int range_max_step = 20;
// the test structure
struct ev_test
{
ev_test(size_t s = 0)
{
m_data.resize(s);
for (auto &c : m_data)
c = 1;
}
std::vector<uint8_t> m_data;
};
//-----------------------------------------------------------------------------
// Type carrier and its support
//----------------------------------------------------------------------------
namespace net
{
using packet = std::vector<char>; // a packet on the wire
class carrier_visitor_base;
class carrier_base // the base in the queue
{
public:
using ptr = std::unique_ptr<carrier_base>;
virtual ~carrier_base() {}
virtual void accept(carrier_visitor_base *p_visitor) = 0;
};
template <typename T>
class carrier;
class carrier_visitor_base
{
public:
virtual ~carrier_visitor_base() {}
virtual void handle(carrier<ev_test> *p_evt) = 0;
virtual void handle(carrier<char> *p_evt) = 0;
virtual void handle(carrier<int> *p_evt) = 0;
};
template <typename T>
class carrier : public carrier_base // the specific carrier
{
public:
explicit carrier() : m_data() {}
explicit carrier(const T &data) : m_data(data) {}
virtual void accept(carrier_visitor_base *p_visitor) override
{
p_visitor->handle(this);
}
T &data() { return m_data; }
private:
T m_data;
};
} // ns net
//----------------------------------------------------------------------------
// external serialization function
//----------------------------------------------------------------------------
BOOST_SERIALIZATION_SPLIT_FREE(ev_test)
namespace boost
{
namespace serialization
{
// serialization function for carrier_base
template <class Archive>
void serialize(Archive &ar, net::carrier_base &t, const unsigned int
version)
{
}
// serialization function for net::carrier<T>
template <class Archive, typename T>
void serialize(Archive &ar, net::carrier<T> &t, const unsigned int
version)
{
ar &boost::serialization::make_nvp(
"carrier_base",
boost::serialization::base_object<net::carrier_base>(t));
auto &data = t.data();
ar &BOOST_SERIALIZATION_NVP(data);
}
// serialization function for ev_test
template <class Archive>
inline void save(Archive &ar, const ev_test &t, const unsigned int
version)
{
size_t size = t.m_data.size();
ar &BOOST_SERIALIZATION_NVP(size);
ar &boost::serialization::make_nvp(
"m_data",
boost::serialization::make_binary_object(const_cast<uint8_t*>(t.m_data.data()),
t.m_data.size()));
}
template <class Archive>
inline void load(Archive &ar, ev_test &t, const unsigned int version)
{
size_t size = 0;
ar &BOOST_SERIALIZATION_NVP(size);
t.m_data.resize(size);
ar &boost::serialization::make_nvp(
"m_data",
boost::serialization::make_binary_object(t.m_data.data(),
t.m_data.size()));
}
}
}
// we must export all carrier
BOOST_SERIALIZATION_SHARED_PTR(net::carrier<ev_test>)
BOOST_CLASS_EXPORT(net::carrier<ev_test>)
//----------------------------------------------------------------------------
// the traits for the boost serialization tests
//----------------------------------------------------------------------------
struct boost_xml_trait
{
static const char *name() { return "boost_xml_test: ev_test: "; }
typedef boost::archive::xml_oarchive oarchive;
typedef boost::archive::xml_iarchive iarchive;
};
struct boost_text_trait
{
static const char *name() { return "boost_text_test: ev_test: "; }
typedef boost::archive::text_oarchive oarchive;
typedef boost::archive::text_iarchive iarchive;
};
struct boost_binary_trait
{
static const char *name() { return "boost_binary_test: ev_test: "; }
typedef boost::archive::binary_oarchive oarchive;
typedef boost::archive::binary_iarchive iarchive;
};
template <typename archive_trait>
struct boost_test
{
static const char *name() { return archive_trait::name(); }
static size_t msg_size() { return 600; }
// throws boost::archive::archive_exception
template <typename T>
static net::packet to_wire(const T &data)
{
using namespace boost::iostreams;
using T1 = typename std::remove_cv<T>::type;
using BT = typename std::remove_reference<T1>::type;
net::carrier_base::ptr p_carrier =
std::make_unique<net::carrier<BT>>(data);
net::packet p;
p.reserve(msg_size());
{
back_insert_device<net::packet> sink(p);
stream<back_insert_device<net::packet>> os{ sink };
typename archive_trait::oarchive oa(os);
oa << BOOST_SERIALIZATION_NVP(p_carrier);
}
return p;
}
// throws boost::archive::archive_exception
static net::carrier_base::ptr from_wire(const net::packet &data)
{
using namespace boost::iostreams;
array_source source{ data.data(), data.size() };
stream<array_source> is{ source };
net::carrier_base::ptr p_carrier;
typename archive_trait::iarchive ia(is); // this takes the most time
ia >> BOOST_SERIALIZATION_NVP(p_carrier);
return p_carrier;
}
};
//----------------------------------------------------------------------------
// XML
//----------------------------------------------------------------------------
static void to_wire_xml(benchmark::State &state)
{
std::locale::global(std::locale("C"));
ev_test data(state.range_x());
while (state.KeepRunning())
{
boost_test<boost_xml_trait>::to_wire(data);
}
state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
state.range_x());
}
BENCHMARK(to_wire_xml)->Range(8, range_mult << range_max_step);
static void from_wire_xml(benchmark::State &state)
{
std::locale::global(std::locale("C"));
auto buffer =
boost_test<boost_xml_trait>::to_wire(ev_test(state.range_x()));
while (state.KeepRunning())
{
boost_test<boost_xml_trait>::from_wire(buffer);
}
state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
state.range_x());
}
BENCHMARK(from_wire_xml)->Range(8, range_mult << range_max_step);
//----------------------------------------------------------------------------
// Text
//----------------------------------------------------------------------------
static void to_wire_text(benchmark::State &state)
{
std::locale::global(std::locale("C"));
ev_test data(state.range_x());
while (state.KeepRunning())
{
boost_test<boost_text_trait>::to_wire(data);
}
state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
state.range_x());
}
BENCHMARK(to_wire_text)->Range(8, range_mult << range_max_step);
static void from_wire_text(benchmark::State &state)
{
std::locale::global(std::locale("C"));
auto buffer =
boost_test<boost_text_trait>::to_wire(ev_test(state.range_x()));
while (state.KeepRunning())
{
boost_test<boost_text_trait>::from_wire(buffer);
}
state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
state.range_x());
}
BENCHMARK(from_wire_text)->Range(8, range_mult << range_max_step);
//----------------------------------------------------------------------------
// Binary
//----------------------------------------------------------------------------
static void to_wire_binary(benchmark::State &state)
{
std::locale::global(std::locale("C"));
ev_test data(state.range_x());
while (state.KeepRunning())
{
boost_test<boost_binary_trait>::to_wire(data);
}
state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
state.range_x());
}
BENCHMARK(to_wire_binary)->Range(8, range_mult << range_max_step);
static void from_wire_binary(benchmark::State &state)
{
std::locale::global(std::locale("C"));
auto buffer =
boost_test<boost_binary_trait>::to_wire(ev_test(state.range_x()));
while (state.KeepRunning())
{
boost_test<boost_binary_trait>::from_wire(buffer);
}
state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
state.range_x());
}
BENCHMARK(from_wire_binary)->Range(8, range_mult << range_max_step);
BENCHMARK_MAIN();
</code>
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