
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>