summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/beast/test/bench/zlib
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/beast/test/bench/zlib')
-rw-r--r--src/boost/libs/beast/test/bench/zlib/CMakeLists.txt31
-rw-r--r--src/boost/libs/beast/test/bench/zlib/Jamfile15
-rw-r--r--src/boost/libs/beast/test/bench/zlib/deflate_stream.cpp199
-rw-r--r--src/boost/libs/beast/test/bench/zlib/inflate_stream.cpp244
4 files changed, 489 insertions, 0 deletions
diff --git a/src/boost/libs/beast/test/bench/zlib/CMakeLists.txt b/src/boost/libs/beast/test/bench/zlib/CMakeLists.txt
new file mode 100644
index 00000000..a030ed93
--- /dev/null
+++ b/src/boost/libs/beast/test/bench/zlib/CMakeLists.txt
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+#
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#
+# Official repository: https://github.com/boostorg/beast
+#
+
+GroupSources (include/boost/beast beast)
+GroupSources (test/extern/zlib-1.2.11 zlib)
+GroupSources (test/bench/zlib "/")
+
+if (MSVC)
+ set_source_files_properties (${ZLIB_SOURCES} PROPERTIES COMPILE_FLAGS "/wd4127 /wd4131 /wd4244")
+endif()
+
+add_executable (bench-zlib
+ ${BOOST_BEAST_FILES}
+ ${ZLIB_SOURCES}
+ Jamfile
+ deflate_stream.cpp
+ inflate_stream.cpp
+)
+target_link_libraries(bench-zlib
+ lib-asio
+ lib-beast
+ lib-test
+ )
+
+set_property(TARGET bench-zlib PROPERTY FOLDER "tests-bench")
diff --git a/src/boost/libs/beast/test/bench/zlib/Jamfile b/src/boost/libs/beast/test/bench/zlib/Jamfile
new file mode 100644
index 00000000..6e210c29
--- /dev/null
+++ b/src/boost/libs/beast/test/bench/zlib/Jamfile
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+#
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#
+# Official repository: https://github.com/boostorg/beast
+#
+
+exe bench-zlib :
+ $(ZLIB_SOURCES)
+ deflate_stream.cpp
+ inflate_stream.cpp
+ /boost/beast/test//lib-test
+ ;
diff --git a/src/boost/libs/beast/test/bench/zlib/deflate_stream.cpp b/src/boost/libs/beast/test/bench/zlib/deflate_stream.cpp
new file mode 100644
index 00000000..321fa98c
--- /dev/null
+++ b/src/boost/libs/beast/test/bench/zlib/deflate_stream.cpp
@@ -0,0 +1,199 @@
+//
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/beast
+//
+
+#include <boost/beast/core/string.hpp>
+#include <boost/beast/zlib/deflate_stream.hpp>
+#include <boost/beast/test/throughput.hpp>
+#include <boost/beast/_experimental/unit_test/dstream.hpp>
+#include <boost/beast/_experimental/unit_test/suite.hpp>
+#include <iomanip>
+#include <random>
+#include <string>
+
+#include "zlib-1.2.11/zlib.h"
+
+namespace boost {
+namespace beast {
+namespace zlib {
+
+class deflate_stream_test : public beast::unit_test::suite
+{
+public:
+ // Lots of repeats, limited char range
+ static
+ std::string
+ corpus1(std::size_t n)
+ {
+ static std::string const alphabet{
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+ };
+ std::string s;
+ s.reserve(n + 5);
+ std::mt19937 g;
+ std::uniform_int_distribution<std::size_t> d0{
+ 0, alphabet.size() - 1};
+ std::uniform_int_distribution<std::size_t> d1{
+ 1, 5};
+ while(s.size() < n)
+ {
+ auto const rep = d1(g);
+ auto const ch = alphabet[d0(g)];
+ s.insert(s.end(), rep, ch);
+ }
+ s.resize(n);
+ return s;
+ }
+
+ // Random data
+ static
+ std::string
+ corpus2(std::size_t n)
+ {
+ std::string s;
+ s.reserve(n);
+ std::mt19937 g;
+ std::uniform_int_distribution<std::uint32_t> d0{0, 255};
+ while(n--)
+ s.push_back(static_cast<char>(d0(g)));
+ return s;
+ }
+
+ std::string
+ doDeflateBeast(string_view const& in)
+ {
+ z_params zs;
+ deflate_stream ds;
+ ds.reset(
+ Z_DEFAULT_COMPRESSION,
+ 15,
+ 4,
+ Strategy::normal);
+ std::string out;
+ out.resize(deflate_upper_bound(in.size()));
+ zs.next_in = in.data();
+ zs.avail_in = in.size();
+ zs.next_out = &out[0];
+ zs.avail_out = out.size();
+ error_code ec;
+ ds.write(zs, Flush::full, ec);
+ BEAST_EXPECTS(! ec, ec.message());
+ out.resize(zs.total_out);
+ return out;
+ }
+
+ std::string
+ doDeflateZLib(string_view const& in)
+ {
+ int result;
+ z_stream zs;
+ memset(&zs, 0, sizeof(zs));
+ result = deflateInit2(
+ &zs,
+ Z_DEFAULT_COMPRESSION,
+ Z_DEFLATED,
+ -15,
+ 4,
+ Z_DEFAULT_STRATEGY
+ );
+ if(result != Z_OK)
+ throw std::logic_error("deflateInit2 failed");
+ std::string out;
+ out.resize(deflateBound(&zs,
+ static_cast<uLong>(in.size())));
+ zs.next_in = (Bytef*)in.data();
+ zs.avail_in = static_cast<uInt>(in.size());
+ zs.next_out = (Bytef*)&out[0];
+ zs.avail_out = static_cast<uInt>(out.size());
+ result = deflate(&zs, Z_FULL_FLUSH);
+ if(result != Z_OK)
+ throw std::logic_error("deflate failed");
+ out.resize(zs.total_out);
+ deflateEnd(&zs);
+ return out;
+ }
+
+ void
+ doCorpus(
+ std::size_t size,
+ std::size_t repeat)
+ {
+ std::size_t constexpr trials = 3;
+ auto const c1 = corpus1(size);
+ auto const c2 = corpus2(size);
+ log <<
+ std::left << std::setw(10) << (std::to_string(size) + "B") <<
+ std::right << std::setw(12) << "Beast" << " " <<
+ std::right << std::setw(12) << "ZLib" <<
+ std::endl;
+ for(std::size_t i = 0; i < trials; ++i)
+ {
+ test::timer t;
+ log << std::left << std::setw(10) << "corpus1";
+ std::string out1;
+ for(std::size_t j = 0; j < repeat; ++j)
+ out1 = doDeflateBeast(c1);
+ auto const t1 =
+ test::throughput(t.elapsed(), size * repeat);
+ log << std::right << std::setw(12) << t1 << " B/s ";
+ std::string out2;
+ for(std::size_t j = 0; j < repeat; ++j)
+ out2 = doDeflateZLib(c1);
+ BEAST_EXPECT(out1 == out2);
+ auto const t2 =
+ test::throughput(t.elapsed(), size * repeat);
+ log << std::right << std::setw(12) << t2 << " B/s";
+ log << std::right << std::setw(12) <<
+ unsigned(double(t1)*100/t2-100) << "%";
+ log << std::endl;
+ }
+ for(std::size_t i = 0; i < trials; ++i)
+ {
+ test::timer t;
+ log << std::left << std::setw(10) << "corpus2";
+ std::string out1;
+ for(std::size_t j = 0; j < repeat; ++j)
+ out1 = doDeflateBeast(c2);
+ auto const t1 =
+ test::throughput(t.elapsed(), size * repeat);
+ log << std::right << std::setw(12) << t1 << " B/s ";
+ std::string out2;
+ for(std::size_t j = 0; j < repeat; ++j)
+ out2 = doDeflateZLib(c2);
+ BEAST_EXPECT(out1 == out2);
+ auto const t2 =
+ test::throughput(t.elapsed(), size * repeat);
+ log << std::right << std::setw(12) << t2 << " B/s";
+ log << std::right << std::setw(12) <<
+ unsigned(double(t1)*100/t2-100) << "%";
+ log << std::endl;
+ }
+ log << std::endl;
+ }
+
+ void
+ doBench()
+ {
+ doCorpus( 16 * 1024, 512);
+ doCorpus( 1024 * 1024, 8);
+ doCorpus(8 * 1024 * 1024, 1);
+ }
+
+ void
+ run() override
+ {
+ doBench();
+ pass();
+ }
+};
+
+BEAST_DEFINE_TESTSUITE(beast,zlib,deflate_stream);
+
+} // zlib
+} // beast
+} // boost
diff --git a/src/boost/libs/beast/test/bench/zlib/inflate_stream.cpp b/src/boost/libs/beast/test/bench/zlib/inflate_stream.cpp
new file mode 100644
index 00000000..ea8d6d98
--- /dev/null
+++ b/src/boost/libs/beast/test/bench/zlib/inflate_stream.cpp
@@ -0,0 +1,244 @@
+//
+// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/beast
+//
+
+#include <boost/beast/core/string.hpp>
+#include <boost/beast/zlib/inflate_stream.hpp>
+#include <boost/beast/test/throughput.hpp>
+#include <boost/beast/_experimental/unit_test/dstream.hpp>
+#include <boost/beast/_experimental/unit_test/suite.hpp>
+#include <iomanip>
+#include <random>
+#include <string>
+
+#include "zlib-1.2.11/zlib.h"
+
+namespace boost {
+namespace beast {
+namespace zlib {
+
+class inflate_stream_test : public beast::unit_test::suite
+{
+public:
+ // Lots of repeats, limited char range
+ static
+ std::string
+ corpus1(std::size_t n)
+ {
+ static std::string const alphabet{
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+ };
+ std::string s;
+ s.reserve(n + 5);
+ std::mt19937 g;
+ std::uniform_int_distribution<std::size_t> d0{
+ 0, alphabet.size() - 1};
+ std::uniform_int_distribution<std::size_t> d1{
+ 1, 5};
+ while(s.size() < n)
+ {
+ auto const rep = d1(g);
+ auto const ch = alphabet[d0(g)];
+ s.insert(s.end(), rep, ch);
+ }
+ s.resize(n);
+ return s;
+ }
+
+ // Random data
+ static
+ std::string
+ corpus2(std::size_t n)
+ {
+ std::string s;
+ s.reserve(n);
+ std::mt19937 g;
+ std::uniform_int_distribution<std::uint32_t> d0{0, 255};
+ while(n--)
+ s.push_back(static_cast<char>(d0(g)));
+ return s;
+ }
+
+ static
+ std::string
+ compress(string_view const& in)
+ {
+ int result;
+ z_stream zs;
+ memset(&zs, 0, sizeof(zs));
+ result = deflateInit2(
+ &zs,
+ Z_DEFAULT_COMPRESSION,
+ Z_DEFLATED,
+ -15,
+ 4,
+ Z_DEFAULT_STRATEGY);
+ if(result != Z_OK)
+ throw std::logic_error("deflateInit2 failed");
+ zs.next_in = (Bytef*)in.data();
+ zs.avail_in = static_cast<uInt>(in.size());
+ std::string out;
+ out.resize(deflateBound(&zs,
+ static_cast<uLong>(in.size())));
+ zs.next_in = (Bytef*)in.data();
+ zs.avail_in = static_cast<uInt>(in.size());
+ zs.next_out = (Bytef*)&out[0];
+ zs.avail_out = static_cast<uInt>(out.size());
+ result = deflate(&zs, Z_FULL_FLUSH);
+ if(result != Z_OK)
+ throw std::logic_error("deflate failed");
+ out.resize(zs.total_out);
+ deflateEnd(&zs);
+ return out;
+ }
+
+ std::string
+ doInflateBeast(string_view const& in)
+ {
+ z_params zs;
+ std::string out;
+ inflate_stream is;
+ zs.next_in = &in[0];
+ zs.avail_in = in.size();
+ out.resize(in.size());
+ zs.next_out = &out[0];
+ zs.avail_out = out.size();
+ for(;;)
+ {
+ error_code ec;
+ is.write(zs, Flush::sync, ec);
+ if(ec)
+ throw std::logic_error("inflate_stream failed");
+ if(zs.avail_out > 0)
+ break;
+ out.resize(2 * zs.total_out);
+ zs.next_out = &out[zs.total_out];
+ zs.avail_out = out.size() - zs.total_out;
+ }
+ out.resize(zs.total_out);
+ return out;
+ }
+
+ std::string
+ doInflateZLib(string_view const& in)
+ {
+ int result;
+ z_stream zs;
+ std::string out;
+ memset(&zs, 0, sizeof(zs));
+ result = inflateInit2(&zs, -15);
+ zs.next_in = (Bytef*)in.data();
+ zs.avail_in = static_cast<uInt>(in.size());
+ out.resize(in.size());
+ zs.next_out = (Bytef*)&out[0];
+ zs.avail_out = static_cast<uInt>(out.size());
+ for(;;)
+ {
+ result = inflate(&zs, Z_SYNC_FLUSH);
+ if( result == Z_NEED_DICT ||
+ result == Z_DATA_ERROR ||
+ result == Z_MEM_ERROR)
+ {
+ throw std::logic_error("inflate failed");
+ }
+ if(zs.avail_out > 0)
+ break;
+ if(result == Z_STREAM_END)
+ break;
+ out.resize(2 * zs.total_out);
+ zs.next_out = (Bytef*)&out[zs.total_out];
+ zs.avail_out = static_cast<uInt>(
+ out.size() - zs.total_out);
+ }
+ out.resize(zs.total_out);
+ inflateEnd(&zs);
+ return out;
+ }
+
+ void
+ doCorpus(
+ std::size_t size,
+ std::size_t repeat)
+ {
+ std::size_t constexpr trials = 3;
+ std::uint64_t constexpr scale = 16;
+ auto const c1 = corpus1(size);
+ auto const c2 = corpus2(size * scale);
+ auto const in1 = compress(c1);
+ auto const in2 = compress(c2);
+ log <<
+ std::left << std::setw(10) << (std::to_string(size) + "B") <<
+ std::right << std::setw(12) << "Beast" << " " <<
+ std::right << std::setw(12) << "ZLib" <<
+ std::endl;
+ for(std::size_t i = 0; i < trials; ++i)
+ {
+ test::timer t;
+ log << std::left << std::setw(10) << "corpus1";
+ std::string out;
+ for(std::size_t j = 0; j < repeat; ++j)
+ out = doInflateBeast(in1);
+ BEAST_EXPECT(out == c1);
+ auto const t1 =
+ test::throughput(t.elapsed(), size * repeat);
+ log << std::right << std::setw(12) << t1 << " B/s ";
+ for(std::size_t j = 0; j < repeat; ++j)
+ out = doInflateZLib(in1);
+ BEAST_EXPECT(out == c1);
+ auto const t2 =
+ test::throughput(t.elapsed(), size * repeat);
+ log << std::right << std::setw(12) << t2 << " B/s";
+ log << std::right << std::setw(12) <<
+ unsigned(double(t1)*100/t2-100) << "%";
+ log << std::endl;
+ }
+ for(std::size_t i = 0; i < trials; ++i)
+ {
+ test::timer t;
+ log << std::left << std::setw(10) << "corpus2";
+ std::string out;
+ for(std::size_t j = 0; j < repeat; ++j)
+ out = doInflateBeast(in2);
+ BEAST_EXPECT(out == c2);
+ auto const t1 =
+ test::throughput(t.elapsed(), size * scale * repeat);
+ log << std::right << std::setw(12) << t1 << " B/s ";
+ for(std::size_t j = 0; j < repeat; ++j)
+ out = doInflateZLib(in2);
+ BEAST_EXPECT(out == c2);
+ auto const t2 =
+ test::throughput(t.elapsed(), size * scale * repeat);
+ log << std::right << std::setw(12) << t2 << " B/s";
+ log << std::right << std::setw(12) <<
+ unsigned(double(t1)*100/t2-100) << "%";
+ log << std::endl;
+ }
+ log << std::endl;
+ }
+
+ void
+ doBench()
+ {
+ doCorpus( 1 * 1024 * 1024, 64);
+ doCorpus( 4 * 1024 * 1024, 16);
+ doCorpus( 16 * 1024 * 1024, 8);
+ }
+
+ void
+ run() override
+ {
+ doBench();
+ pass();
+ }
+};
+
+BEAST_DEFINE_TESTSUITE(beast,zlib,inflate_stream);
+
+} // zlib
+} // beast
+} // boost