读取输入文件,最快的方式可能
read input files, fastest way possible?
我有许多浮点数形式的数据文本文件。我正在寻找在c++中阅读它们的最快方法。如果最快的话,我可以把文件变成二进制文件。
如果你能给我提示或给我一个完整的解释网站,那就太好了。我不知道是否有任何图书馆能快速完成这项工作。即使有任何开源软件可以完成这项工作,也会很有帮助。
使用二进制文件是最快的选择。你不仅可以在一个单一的操作中直接在一个原始的istream::read
数组中读取它(这是非常快的),而且你甚至可以在内存中映射文件,如果你的操作系统支持它;您可以在POSIX系统上使用open
/mmap
,在Windows上使用CreateFile
/CreateFileMapping
/MapViewOfFile
,甚至可以使用Boost跨平台解决方案(感谢@Cory Nelson指出它)。
快速,肮脏的示例,假设文件包含一些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);
瓶颈在I/O。您希望程序以最少的I/O调用将尽可能多的数据读入内存。例如,读取256个带有一个fread
的数字比读取256个带有一个fread
的数字要快。
如果可以,格式化数据文件以匹配目标平台的内部浮点表示,或者至少是您的程序的表示。这减少了将文本表示转换为内部表示的开销。
绕过操作系统,如果可能的话,使用DMA控制器读取文件数据。DMA芯片减轻了处理器将数据读入内存的负担。
压缩数据文件。数据文件希望位于磁盘上一组连续的扇区中。这将减少在物理盘片上寻找不同区域所花费的时间。
程序要求独占控制磁盘资源和处理器吗?阻止所有其他不重要的任务;提高程序执行的优先级。
使用多个缓冲区来保持磁盘驱动器旋转。大部分时间花在等待硬盘加速和减速上。您的程序可以处理数据,而其他程序将数据存储到缓冲区中,这导致…
多线程。创建一个线程来读取数据,并在缓冲区不为空时通知处理任务。
这些应该能让你忙上一阵子。所有其他优化所带来的性能增益都可以忽略不计。(例如直接访问硬盘驱动器控制器以传输到您的一个缓冲区)
编译模式的另一个注意事项。我试过解析一个有1M行的文件。调试模式花费50秒来解析数据并将其附加到容器中。释放模式消耗至少快10倍,约为4秒。下面的代码是在使用istringstream将数据解析为2D点(,)之前读取整个文件。
vector <float> in_data;
string raw_data;
ifstream ifs;
ifs.open(_file_in.c_str(), ios::binary);
ifs.seekg(0, ios::end);
long length = ifs.tellg();
ifs.seekg(0, ios::beg);
char * buffer;
buffer = new char[length];
ifs.read(buffer, length);
raw_data = buffer;
ifs.close();
delete[]buffer;
cout << "Size: " << raw_data.length()/1024/1024.0 << "Mb" << endl;
istringstream _sstr(raw_data);
string _line;
while (getline(_sstr, _line)){
istringstream _ss(_line);
vector <float> record;
//maybe using boost/Tokenizer is a good idea ...
while (_ss)
{
string s;
if (!getline(_ss, s, ',')) break;
record.push_back(atof(s.c_str()));
}
in_data.push_back(record[0]);
}
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 当可输入框在窗口中处于活动状态时获得通知的任何方法
- 在数组中输入 n 个整数的列表,并以类似于钟摆来回移动的方式排列它们. 输入-1 3 2 5 4,输出5 3 1 2 4
- C ++异步键盘输入(标准方式)
- 是否可以在命令行中将输入参数传递给可执行文件
- 如何使用打印到 PDF 打印机在 MFC 和 CView 中以编程方式打印而不提示输入文件名?
- 适用于 macOS 的 Xcode 应用程序。这就是我设置从USB麦克风输入获取音频的方式。一年前工作,现在没有了。为什么
- 以编程方式防止重命名或删除文件,但仍使其可写
- 提供变量作为 MATLAB 系统命令的输入参数,以便C++可执行文件
- 用于了解输入和输出流缓冲区实际工作方式的程序
- RXCPP:创建一个不关心可观察量输入类型的扩展
- 可视C++ - 从链接器>输入>其他依赖项中排除文件
- 可选类输入中的 C++ 填充向量
- 如何以可移植方式删除名称为 wchar_t 类型的文件C++
- 是否有一种非间接、非黑客的方式来保证 constexpr 函数仅在编译时可调用?
- 如何以有效的方式将输入参数传递给函数
- 使 c++ 程序以交互方式将输入输出传递给 windows 命令 prommpt
- C++:如何使用CIN和File两种方式获取输入
- 以下代码以意外的方式获取输入
- 以较小、更频繁的读取或较大的读取方式读取输入