【发布时间】:2014-09-28 17:17:30
【问题描述】:
在我的情况下,我有不同的文件,假设我有 >4GB 的数据文件。我想逐行读取该文件并处理每一行。我的限制之一是软件必须在 32 位 MS Windows 或 64 位上运行,并具有少量 RAM(最小 4GB)。您还可以假设这些行的处理不是瓶颈。
在当前解决方案中,我通过ifstream 读取该文件并复制到某个字符串。这是 sn-p 的样子。
std::ifstream file(filename_xml.c_str());
uintmax_t m_numLines = 0;
std::string str;
while (std::getline(file, str))
{
m_numLines++;
}
好吧,这行得通,但慢慢来,我的 3.6 GB 数据是时候了:
real 1m4.155s
user 0m0.000s
sys 0m0.030s
我正在寻找一种比这更快的方法,例如我发现 How to parse space-separated floats in C++ quickly? 并且我喜欢使用 boost::mapped_file 提供的解决方案,但我遇到了另一个问题,如果我的文件很大并且在我的案例文件 1GB 大足以放弃整个过程。我必须关心内存中的当前数据,可能使用该工具的人安装的 RAM 不超过 4 GB。
所以我从 boost 中找到了 mapped_file,但在我的情况下如何使用它?是否可以部分读取该文件并接收这些行?
也许你有另一个更好的解决方案。我只需要处理每一行。
谢谢,
巴特
【问题讨论】:
-
您只能映射文件的一部分。
-
memmapping 会将整个文件映射到内存空间。这是不可能的,因为您的文件会占用进程的整个可寻址空间。您需要“窗口化”文件,因此在任何给定时间通过您的 memmap 区域只能看到文件的较小部分。
-
如果连续运行两次,统计数据是多少?用户或系统时间几乎为零的事实意味着大部分时间都花在了 I/O 上。除非您有足够的内存来缓存整个文件,否则转到内存映射文件不会提高速度(因为需要分页数据)。
-
典型的 7200 rpm 主轴磁盘驱动器最多可以以 60 MB/秒的速度读取。 3.6 GB 需要 1 分钟才能读取,无论您编写哪种代码。您需要更快的磁盘或停止等待程序完成。
-
@bioky - 当不使用磁盘但数据来自文件系统缓存并且机器有足够的 RAM 时,它会快很多。重复运行程序时的典型基准风险。
标签: c++ boost large-files 32-bit data-processing