2011-08-23 67 views
6

我正在尝试将c#程序迁移到C++。 c#程序逐行读取一个1〜5 gb大小的文本文件,并对每行进行一些分析。这个C#代码如下所示。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秒。

将最后2个代码解析为char []而不是字符串的代码都需要大约30秒的时间才能将char []转换为字符串。

有没有一种方法可以提高c/C++代码的性能来逐行读取文本文件以匹配c#的性能? (补充:我使用Windows用VC++ 10.0 7 64位操作系统,64位)

+0

你的问题是类似于这个线程http://stackoverflow.com/questions/7102087/how-to-enhance-the-speed-of-my-c-program-in-reading-delimited-text-files/ 7102179#7102179 –

+1

一个有趣的问题是:C#如何做到这一点?这会给你一些关于他们使用什么优化的信息,并可能提供一些信息。 – ssube

回答

9

之一,以提高文件读取性能的最佳方法之一是使用内存映射文件(mmap()在Unix,Windows上CreateFileMapping()等)。然后你的文件作为一个平坦的字节块出现在内存中,你可以比缓冲I/O更快地读取它。

对于大于千兆字节左右的文件,您将希望使用64位操作系统(使用64位进程)。我已经完成了这项工作,以Python的方式处理30 GB文件,并获得了很好的结果

0

我建议两两件事:

使用f.rdbuf()->pubsetbuf(...)设置一个更大的读取缓冲区。我注意到当使用更大的缓冲区大小时,fstream性能有了非常显着的增长。

而不是getline(...)使用read(...)来读取较大的数据块并手动解析它们。

0

编译优化。 C++有相当一些优化器将删除的理论开销。例如。许多简单的字符串方法将被内联。这可能就是为什么你的char[2000]版本更快。