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

时间:2011-07-19 22:57:31

标签: c++ input binary

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

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

2 个答案:

答案 0 :(得分:26)

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

快速&脏示例,假设文件包含某些float s的原始表示:

“正常”读:

#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();

使用共享内存:

#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);

答案 1 :(得分:7)

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

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

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

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

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

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

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

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