读取C ++中的大型CSV文件(〜4GB)

Jon*_*n V 2 c++ csv parsing file large-files

我想读取一个大型CSV文件并将其存储到地图中。我首先读取文件,然后查看处理需要多长时间。这是我的循环:

while(!gFile.eof()){
   gFile >> data;
}
Run Code Online (Sandbox Code Playgroud)

我需要35分钟才能处理包含3500万行和6列的csv文件。有什么办法可以加快速度吗?对SO来说还很陌生,如果不能正确询问,请您道歉。

Tho*_*ews 5

后台
文件是流设备或概念。读取文件最有效的用法是保持数据流(流)。每笔交易都有开销。数据传输越大,对开销的影响越小。因此,目标是保持数据流通。

内存比文件访问快
搜索内存比搜索文件快很多倍。因此,搜索“单词”或定界符比逐个读取文件来查找定界符要快得多。

方法1:逐行
使用std::getline比使用快得多operator>>。尽管输入代码可以读取数据块;您只执行一次事务以读取一条记录,而不是每列一次。请记住,保持数据畅通,并在内存中搜索列更快。

方法2:块读取
为了保持流的连续性,将一块内存读入一个缓冲区(大缓冲区)。处理缓冲区中的数据。这比逐行读取效率更高,因为您可以通过一个事务读取多行数据,从而减少了事务开销。

一个警告是您可能具有记录跨缓冲区边界,因此您需要提出一种算法来处理该问题。执行代价很小,每个事务仅发生一次(考虑事务开销的这一部分)。

方法3:多线程
本着保持数据流传输的精神,您可以创建多个线程。一个线程负责或将数据读入缓冲区,而另一个线程处理缓冲区中的数据。这项技术可以更好地保持数据畅通。

方法4:双缓冲和多个线程
这采用上面的方法3,并添加了多个缓冲区。读取线程可以填充一个缓冲区,然后开始填充第二个缓冲区。数据处理线程将等待,直到第一个缓冲区被填充,然后再处理数据。使用此技术可以更好地使读取数据的速度与处理数据的速度相匹配。

方法5:内存映射文件
有了内存映射文件,操作系统将按需处理将文件读入内存的过程。您只需编写较少的代码,但是对于何时将文件读入内存却无法获得太多控制。这仍然比逐场阅读要快。

  • 反对者:请添加评论来解释您的反对票。我亲自实施了这些技术,并在处理超过 1GB 的数据文件时发现了显着的性能改进。 (3认同)