我正在尝试减少 C++ 中 boost 档案的内存大小。
我发现的一个问题是,Boost 的二进制存档默认对任何 int 使用 4 个字节,无论其大小如何。因此,我发现空的 boost 二进制存档需要 62 个字节,而空的文本存档需要 40 个字节(空文本存档的文本表示形式:22 serialization::archive 14 0 0 1 0 0 0 0 0
).
有什么方法可以改变整数的默认行为吗?
另外,除了对向量使用 make_array 之外,还有其他方法可以优化二进制存档的大小吗?
-
Q. 我正在尝试减少 C++ 中 boost 档案的内存大小。
See Boost C++ 序列化开销
-
Q. 我发现的一个问题是,Boost 的二进制存档默认对任何 int 使用 4 个字节,无论其大小如何。
那是因为它是序列化库,而不是压缩库
-
Q. 因此,我发现空的 boost 二进制存档需要 62 个字节,而空的文本存档需要 40 个字节(空文本存档的文本表示形式:22 serialization::archive 14 0 0 1 0 0 0 0 0)。
使用存档标志:例如从Boost序列化:如何预测序列化结果的大小?:
- 调整内容(boost::archive::no_codecvt、boost::archive::no_header、禁用跟踪 etc.)
-
Q. 有什么方法可以改变整数的默认行为吗?
没有。有BOOST_IS_BITWISE_SERIALIZABLE(T)
虽然(参见例如提高序列化按位序列化能力示例和解释)。
-
Q. 另外,除了使用之外,还有其他方法来优化二进制存档的大小吗make_array
对于向量?
Using make_array
没有帮助vector<int>
:
Live On Coliru
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <sstream>
#include <iostream>
static auto const flags = boost::archive::no_header | boost::archive::no_tracking;
template <typename T>
std::string direct(T const& v) {
std::ostringstream oss;
{
boost::archive::binary_oarchive oa(oss, flags);
oa << v;
}
return oss.str();
}
template <typename T>
std::string as_pod_array(T const& v) {
std::ostringstream oss;
{
boost::archive::binary_oarchive oa(oss, flags);
oa << v.size() << boost::serialization::make_array(v.data(), v.size());
}
return oss.str();
}
int main() {
std::vector<int> i(100);
std::cout << "direct: " << direct(i).size() << "\n";
std::cout << "as_pod_array: " << as_pod_array(i).size() << "\n";
}
Prints
direct: 408
as_pod_array: 408
压缩
最直接的优化方法是压缩结果流(另请参阅添加的基准here).
除此之外,您将必须覆盖默认序列化并应用您自己的压缩(可以是简单的游程编码、霍夫曼编码或更特定于域的编码)。
Demo
Live On Coliru
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <sstream>
#include <iostream>
#include <boost/iostreams/filter/bzip2.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/copy.hpp>
static auto const flags = boost::archive::no_header | boost::archive::no_tracking;
template <typename T>
size_t archive_size(T const& v)
{
std::stringstream ss;
{
boost::archive::binary_oarchive oa(ss, flags);
oa << v;
}
std::vector<char> compressed;
{
boost::iostreams::filtering_ostream fos;
fos.push(boost::iostreams::bzip2_compressor());
fos.push(boost::iostreams::back_inserter(compressed));
boost::iostreams::copy(ss, fos);
}
return compressed.size();
}
int main() {
std::vector<int> i(100);
std::cout << "bzip2: " << archive_size(i) << "\n";
}
Prints
bzip2: 47
压缩率约为 11%(如果删除存档标志,压缩率约为 19%)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)