2011-10-10 108 views
5

与一次读取整个文件相比,逐行读取一行时是否存在显着差异(理论上)?一次一行读取文件时的性能vs读取整个文件

读取整个文件确实会对使用的内存量产生负面影响,但它的运行速度会更快吗?

我需要读取一个文件并处理每一行。我不知道是否应该一次读一行并处理它,或者读取整个文件,处理所有文件,然后写入输出。

我已经设置了prgm逐行读取,我想知道是否值得努力将其更改为读取整个文件(不容易给出我的设置)。

感谢,

+1

从理论上讲,驱动器可能不得不逐行寻找和阅读更多的程序,具体取决于发生了什么。实际上,这可能不是问题,因为缓冲的文件I/O可能被用于读取较大的块。您的里程将根据您的硬件和算法的细节而有所不同。在进行优化时,您必须期望编写多个程序迭代,并添加计时器代码或使用分析器来查找哪些时间最长。 – holtavolt

回答

0

说实话,攻读我的学位期间,而效率后,我来到了这个结论对你的问题:这取决于这个文件要多久被读取。如果你只读过一次,那就做完整件事情,因为那样只会解放其他任务的过程。 还有一件事要留在你的脑海里,是文件将在稍后编辑并需要更新(如在读取更新的部分?)如果是这样的话,你可能需要设置一个标记来重新调整从哪里读取(然后再次多久更新一次?)。但是,如果是一次性工作,那么只要不需要在文件中创建特定文字的标记就可以继续阅读。 希望这有助于。

+0

在任何现代的* nix或windows操作系统中,操作系统都会为您完成这种操作(缓冲,进程间共享,标记更新)。 –

+0

我同意....有时当人们的效率太严重,他们实际上变得更糟!即通过执行/干涉缓冲,在进程之间共享,标记更新。 –

0

将整个文件读入内存通常不是一个好主意,因为这些文件可能很大并且可能占用大量内存,在最坏情况下会导致内存不足。因此,为了平衡性能和内存使用量,您需要将一个文件块读入缓冲区并通过缓冲区进行解析。处理完块后,读取下一个块直到EOF。

决定一个好的块大小将必须根据你想要达到的目的来完成。

+1

文件系统将为您执行所有“块”操作!它的被称为缓冲区管理,在OS缓冲之上实现自己的缓冲只会减慢你的速度。 –

+0

@詹姆斯安德森 - 你是对的:)我只是把它作为OP提到的“理论上”的独家。 – srikanta

2

读取整个文件会稍快一些 - 但不会太多!

但是,要小心读取整个文件不可扩展,因为受限于系统中的可用内存,一旦文件大小超过了RAM程序的大小,它将开始使用交换空间将会慢得多。如果文件大小超过可用虚拟内存的大小,则程序将崩溃。

0

其中一个因素是您要读取多少数据,以及程序最初需要运行多长时间,即运行性能是否有任何好处。

请参阅this answer中的书中关于思考软件性能的一般性建议。

(我知道你在理论上答案,但何时担心性能这方面也很重要,只要你有一个有限的时间支出金额)。

1

与其他人一样,我相信做更大的读取会提高你的应用程序的性能,但不要期待奇迹,I/O已经在操作系统层被缓冲了,所以你只能通过减少有太多读取调用的开销来获得。一次读取整个文件是危险的,除非您知道输入文件的最大可能大小。最合理的方法是以大块读取文件。

如果您想进一步改进,您应该考虑将I/O与处理重叠。假设您以128MB的块读取输入文件。在您的主线程上,您读取第一个128MB的块,然后将其传递给工作线程进行处理。当工作线程开始工作时,主线程读取第二个128MB的数据块。从那时起,当工作者线程正在处理块N时,主线程正在从磁盘读取块N + 1。

0

我认为这将取决于您的应用程序的需求(就像我知道的大多数事情一样)。读取节点js中的1 MB文件的速度比使用可读流或线性阅读器的fs.readFile()快3-4倍,只要读取文件即可。如果文件非常大并且您正在处理输入,则流可能会提供一些额外的性能。如果你的应用程序已经占用了大量内存,那么它也可能是理想的,因为Node进程在64位系统上的内存限制约为1.5GB。如果数据源相对于cpu可以处理它的速度较慢(在HDD或磁带上归档,像TCP这样的网络连接),那么处理数据块时它们也可能更具性能。至于将文件读入内存或将其传输到内存中,我猜测发送数据事件的函数调用开销和切换到处理函数回调会减慢进程。