c++文本文件读取性能
本文关键字:性能 读取 文件 文本 c++ | 更新日期: 2023-09-27 18:06:28
我正在尝试将c#程序迁移到c++。c#程序逐行读取1~ 5gb大小的文本文件,并对每行进行一些分析。c#代码如下:
using (var f = File.OpenRead(fname))
using (var reader = new StreamReader(f))
while (!reader.EndOfStream) {
var line = reader.ReadLine();
// do some analysis
}
对于一个有700万行、1.6 gb的文件,这段代码大约需要18秒。
我首先编写的迁移c++代码如下
ifstream f(fname);
string line;
while (getline(f, line)) {
// do some analysis
}
上面的c++代码大约需要420秒。我写的第二段c++代码如下:
ifstream f(fname);
char line[2000];
while (f.getline(line, 2000)) {
// do some analysis
}
上面的c++大约需要85秒。
我最后尝试的代码是c代码,如下所示。
FILE *file = fopen ( fname, "r" );
char line[2000];
while (fgets(line, 2000, file) != NULL ) {
// do some analysis
}
fclose ( file );
上面的c代码大约需要33秒。
最后两个代码都将行解析为char[]而不是字符串,将char[]转换为字符串需要大约30秒。
是否有一种方法可以提高c/c++代码的性能来逐行读取文本文件以匹配c#性能?(补充:我使用windows 7 64位操作系统与vc++ 10.0, x64)
提高文件读取性能的最佳方法之一是使用内存映射文件(Unix上的mmap()
, Windows上的CreateFileMapping()
等)。然后你的文件在内存中显示为一个平坦的字节块,你可以读它比做缓冲I/o快得多。
对于大于1 gb左右的文件,您将希望使用64位操作系统(带有64位进程)。我已经用Python处理了一个30gb的文件,效果非常好。
我建议两件事:
使用f.rdbuf()->pubsetbuf(...)
设置更大的读缓冲区。我注意到当使用更大的缓冲区时,fstream性能有了一些非常显著的提高。
代替getline(...)
使用read(...)
读取更大的数据块并手动解析它们
优化编译。c++有相当多的理论开销,优化器将消除这些开销。例如,许多简单的字符串方法将被内联。这可能就是为什么你的char[2000]
版本更快。