读取输入文件,最快的方式?

Kia*_*ash 17 c++ binary input

我有许多浮点数形式的数据文本文件.我正在寻找用C++阅读它们的最快方法.如果这是最快的话,我可以将文件更改为二进制文件.

如果您能给我提示或将我推荐给一个有完整解释的网站,那就太棒了.我不知道是否有任何库可以快速完成工作.即使有任何开源软件可以完成这项工作,这也会有所帮助.

Mat*_*lia 27

拥有二进制文件是最快的选择.您不仅可以istream::read在一个操作中直接在一个数组中读取它(这非常快),但是如果您的操作系统支持,您甚至可以将文件映射到内存中; 你可以使用open/ mmap在POSIX系统上CreateFile/ CreateFileMapping/ MapViewOfFile在Windows上,甚至是Boost跨平台解决方案(感谢@Cory Nelson指出它).

快速和脏的例子,假设文件包含一些floats 的原始表示:

"正常"读:

#include <fstream>
#include <vector>

// ...

// Open the stream
std::ifstream is("input.dat");
// Determine the file length
is.seekg(0, std::ios_base::end);
std::size_t size=is.tellg();
is.seekg(0, std::ios_base::beg);
// Create a vector to store the data
std::vector<float> v(size/sizeof(float));
// Load the data
is.read((char*) &v[0], size);
// Close the file
is.close();
Run Code Online (Sandbox Code Playgroud)

使用共享内存:

#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>

using boost::interprocess;

// ....

// Create the file mapping
file_mapping fm("input.dat", read_only);
// Map the file in memory
mapped_region region(fm, read_only);
// Get the address where the file has been mapped
float * addr = (float *)region.get_address();
std::size_t elements  = region.get_size()/sizeof(float);
Run Code Online (Sandbox Code Playgroud)

  • [Boost Interprocess](http://www.boost.org/doc/libs/1_47_0/doc/html/interprocess/sharedmemorybetweenprocesses.html#interprocess.sharedmemorybetweenprocesses.mapped_file)提供跨平台的内存映射文件. (6认同)
  • @yi_H:我认为`mmap`不会比`read`慢. (2认同)
  • 我不知道这是否有帮助,但我已经使用“正常读取”和“共享内存读取”进行了读取 1000 万个浮点数的测试。使用 O3 优化,正常读取需要 185 毫秒,增强读取需要 328 毫秒。O3 将正​​常读取速度提高 100%,但不会改变提升读取速度。 (2认同)

Tho*_*ews 7

你的瓶颈在于I/O. 您希望程序在最少的I/O调用中将尽可能多的数据读入内存.例如,用一个读取256个数字freadfread一个数字的256个快.

如果可以,请格式化数据文件以匹配目标平台的内部浮点表示,或至少与程序的表示形式相匹配.这减少了将文本表示转换为内部表示的开销.

如果可能,绕过OS并使用DMA控制器读入文件数据.DMA芯片负责将数据从处理器的肩部读入存储器.

压缩数据文件.数据文件希望位于磁盘上的一个连续扇区集中.这将减少在物理盘片上寻找不同区域所花费的时间.

您是否需要对磁盘资源和处理器进行独占控制.阻止所有其他不重要的任务; 提高程序执行的优先级.

使用多个缓冲区来保持磁盘驱动器旋转.花费大部分时间等待硬盘加速和减速.您的程序可以处理数据,而其他东西将数据存储到缓冲区,这导致......

多线程.创建一个线程来读入数据,并在缓冲区不为空时提醒处理任务.

这些应该让你忙一阵子.所有其他优化将导致可忽略的性能提升.(例如直接访问硬盘驱动器控制器以转移到其中一个缓冲区.)