我正在运行物理模拟,我想改进它处理数据的方式。我正在保存并读取包含一个浮点数然后两个整数的文件,然后是512 * 512 = 262144 +1或-1,最后每个数据文件加权595 kb。所有这些数字都由一个空格分隔。
我正在保存数十万个这样的文件,所以它很快就会增加存储量的gigas,我想知道是否有一种快速(希望轻松的cpu-effort-wise方式)压缩和解压缩这种类型随时可用的数据(我的意思是在使用之前/之后没有使用)。
我到底能节省多少钱?
答案 0 :(得分:4)
如果你想要相对快速的读写,你可能想要以“二进制”格式存储和读取它们,即它们以字节内部存储的方式本机。浮点数使用4个字节的数据,存储大量数据时不需要任何“分隔符”。
为此,您可以考虑boost's "serialize" library。
请注意,使用数据压缩方法(zlib等)可以节省您存储的字节数,但压缩和解压缩它们的速度相对较慢。
以二进制格式存储不仅会占用较少的磁盘存储空间(比以文本格式存储),而且还应该更高性能,不仅因为文件I / O较少,而且还因为没有字符串写入/解析
请注意,当您输入/输出到binary_iarchive
或binary_oarchive
时,您会传入基础istream
或ostream
,如果这是一个文件,则需要将其打开带有ios::binary
标志,因为可能转换了行结尾的问题。
即使您确定数据压缩(zlib或其他库)是可行的方法,仍然值得使用boost :: serialize将数据转换为“blob”进行压缩。在这种情况下,您可能会使用std::ostringstream
作为输出流来创建blob。
顺便提一下,如果你有2 ^ 18个“boolean”值只能是1或-1,那么每个只需1位,(它们将物理存储为1或0,但你会在逻辑上翻译它) 。那将是2 ^ 15字节,这是32K而不是595K
答案 1 :(得分:1)
鉴于有关有效数据的额外信息,请按以下方式定义您的类: -
class Data
{
float m_float_value;
int m_int_value_1, m_int_value_2;
unsigned m_weights [8192];
};
然后使用二进制文件IO将此类传入和传出文件,不要转换为文本!
权重存储为布尔值,打包成无符号整数。
要获得权重,请添加一个访问者: -
int Data::GetWeight (size_t index)
{
return m_weights [index >> 5] & (1 << (index & 31)) ? 1 : -1;
}
如果类数据中没有打包,这将为您提供32780字节(5.4%)的数据文件。
答案 2 :(得分:0)
我建议如果你担心大小,二进制格式将是“压缩”你的数据最有用的方法。听起来你正在处理以下内容:
struct data {
float a;
int b, c;
signed char d[512][512];
};
someFunc() {
data* someData = new data;
std::ifstream inFile("inputData.bin", std::ifstream::binary);
std::ofstream outFile("outputData.bin", std::ofstream::binary);
// Read from file
inFile.read(someData, sizeof(data));
inFile.close();
// Write to file
outFile.write(someData, sizeof(data));
outFile.close();
delete someData;
}
我还应该提一下,如果你将+ 1 / -1编码为比特,你应该节省大量空间(在我在这里展示的另一个因子为8)。
答案 3 :(得分:0)
对于这些数据,任何自制的东西都不会在高质量的开源二进制存储库中运行。对于此类存储要求,请尝试boost serialize或 - HDF5。我已经在一些具有非常大量double
,float
,long
和int
数据的项目上成功使用了HDF5。发现它很有用,可以控制每个“文件”的压缩率 vs cpu-effort。将数百万个“文件”存储在分层结构的单个“磁盘”文件中也很有用。美国国家航空航天局 - 可能会剥夺我的风格;) - 也使用它。