从文件中读取不是逐行的

时间:2009-06-26 12:52:55

标签: c++ performance qt file filesystems

QTextStream分配给QFile并逐行读取它很容易并且工作正常,但我想知道是否可以通过先将文件存储在内存然后处理中来提高性能它是逐行的。

使用sysinternals中的FileMon,我遇到的文件是以16KB的块读取的,因为我要处理的文件不是那么大(~2MB,但很多!),将它们加载到记忆将是一件好事。

任何想法我该怎么办? QFile来自QIODevice,它允许我将ReadAll()转换为QByteArray,但是如何继续将其划分为行?

4 个答案:

答案 0 :(得分:4)

QTextStream具有ReadAll功能:

http://doc.qt.io/qt-4.8/qtextstream.html#readAll

当然,这就是你所需要的一切吗?

或者你可以全部读入QByteArray,而QTextStream可以将其作为输入而不是QFile。

答案 1 :(得分:2)

小心点。需要考虑很多效果。

对于所涉及的字符串处理(或者对文件执行的任何操作),如果文件缓冲是合理的,则从内存中执行此操作与逐行执行文件之间可能没有性能差异。

实际上,调用操作系统进行低级读取非常昂贵。这就是我们缓冲I / O的原因。对于小I / O大小,呼叫的开销占主导地位。因此,一次读取64个字节的效率可能是一次读取256个字节的1/4。 (我在这里谈的是read(),而不是fgets()或fread()这两个都是缓冲的。)

在某个时刻,物理I / O所需的时间开始占主导地位,而当较大的缓冲区的性能没有增加太多时,您就找到了缓冲区大小。非常老的数据点:7MHz Amiga 500,100MB SCSI硬盘(A590 + Quantum):我的I / O性能实际上只有256KB缓冲区大小才达到最大值。与处理器相比,那个磁盘很快! (计算机只有3MB的RAM。256KB是一个大缓冲区!)

然而,你可以有太多好事。一旦您的文件在内存中,操作系统可以在闲暇时将该文件分页回磁盘。如果它这样做,你就失去了缓冲的任何好处。如果你的缓冲区太大,那么这可能会在某些负载情况下发生,并且你的性能下降到厕所。因此,请仔细考虑您的运行时环境,并在需要时限制内存占用。

另一种方法是使用mmap()将文件映射到内存中。现在,操作系统不会将您的文件分页 - 相反,它只是不会页面进入,或者如果它需要内存,它将丢弃缓存在核心中的任何文件。但是它不需要为交换空间写任何东西 - 它有可用的文件。但是,我不确定这是否会带来更好的性能,因为在大块中进行I / O仍然会更好,虚拟内存往往会以页面大小的块移动。一些内存管理器可以在块中移动页面以增加I / O带宽和预取页面。但我还没有详细研究过这个问题。

首先让您的程序正常运行。然后优化。

答案 2 :(得分:1)

只要每次读取单行时都不打开和关闭文件,读取整个文件或在读取时都应该没有性能差异(除非处理部分更快)当你有整个文件使用时)。如果你考虑一下,两种方式实际上都在做同样的事情(读完整个文件一次)。

答案 3 :(得分:0)

你可以

QTextStream ( QIODevice * device )
  

QTextStream类为阅读和提供了方便的界面   写文本。

     

QTextStream可以在QIODevice,QByteArray或QString上运行。   使用QTextStream的流媒体操作符,您可以方便地阅读和   写单词,行和数字。