c++ - 如何加快从文件流中加载 15M 整数?

标签 c++ stl stream

我有一个预先计算的整数数组,它是 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/

相关文章:

java - 如果打开 JarFile 时抛出 I/O 错误,我应该关闭它吗? (处理流的一般规则是否适用?)

c++ - 从C++ OpenCV中的findNonZero函数仅复制Mat的行索引

c++ - 如何在 Mixin 类中按类型返回组件?

c++ - 我的迭代器没有按照预期的方式工作

c++ - 使用与索引不同的类访问 C++ 映射

iOS 流媒体背景音频

c# - 我应该关闭 WCF REST 服务中的流吗?

c++ - 指针地址

c++ - 在哪里可以看到 C++ 字符串函数 c_str 的代码

c++ - 为什么 unique_lock 调用解锁,当他不拥有互斥量?