我有一个预先计算的整数数组,它是 15M 值的固定大小。我需要在程序启动时加载这些值。目前加载最多需要 2 分钟,文件大小约为 130MB。有什么办法可以加快加载速度。我也可以随意更改保存过程。
std::array<int, 15000000> keys;
std::string config = "config.dat";
// how array is saved
std::ofstream out(config.c_str());
std::copy(keys.cbegin(), keys.cend(),
std::ostream_iterator<int>(out, "\n"));
// load of array
std::ifstream in(config.c_str());
std::copy(std::istream_iterator<int>(in),
std::istream_iterator<int>(), keys.begin());
in_ranks.close();
提前致谢。
已解决。使用了接受的答案中提出的方法。现在只需眨眼。
感谢大家的见解。
最佳答案
关于写入和读取操作的速度有两个问题。
首先,std::copy 在写入 output_iterator 时无法进行 block 复制优化,因为它无法直接访问底层目标。
其次,您将整数作为 ascii 而不是二进制写入,因此对于您的写入 output_iterator 的每次迭代都会创建您的 int 的 ascii 表示,并且在读取时它必须将文本解析回整数。我相信这是您的性能问题的首当其冲。
您的数组的原始存储空间(假设是 4 字节整数)应该只有 60MB,但是由于 ascii 中整数的每个字符都是 1 字节,因此任何超过 4 个字符的整数都将比二进制存储空间大,因此你的 130MB 文件。
没有一种简单的方法可以便携地解决您的速度问题(以便文件可以在不同的字节序或整数大小的机器上读取)或使用 std::copy 时。最简单的方法是将整个数组转储到磁盘,然后使用 fstream.write 和 read 将其全部读回,请记住它不是严格可移植的。
写作:
std::fstream out(config.c_str(), ios::out | ios::binary);
out.write( keys.data(), keys.size() * sizeof(int) );
阅读:
std::fstream in(config.c_str(), ios::in | ios::binary);
in.read( keys.data(), keys.size() * sizeof(int) );
----更新----
如果您真的关心可移植性,您可以轻松地在分发工件中使用可移植格式(如您的初始 ascii 版本),然后当程序首次运行时,它可以将该可移植格式转换为本地优化的版本,以供后续使用处决。
可能是这样的:
std::array<int, 15000000> keys;
// data.txt are the ascii values and data.bin is the binary version
if(!file_exists("data.bin")) {
std::ifstream in("data.txt");
std::copy(std::istream_iterator<int>(in),
std::istream_iterator<int>(), keys.begin());
in.close();
std::fstream out("data.bin", ios::out | ios::binary);
out.write( keys.data(), keys.size() * sizeof(int) );
} else {
std::fstream in("data.bin", ios::in | ios::binary);
in.read( keys.data(), keys.size() * sizeof(int) );
}
如果你有一个安装过程,这个预处理也可以在那个时候完成......
关于c++ - 如何加快从文件流中加载 15M 整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3415161/