逐行读取文件与读取整个文件时的性能

Performance when reading a file line by line vs reading the whole file

本文关键字:读取 文件 性能 逐行      更新时间:2023-10-16

与一次读取整个文件相比,逐行读取while是否有明显的差异(理论上)?

读取整个文件确实对所使用的内存量有负面影响,但它是否工作得更快?

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

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

谢谢,

读取整个文件会稍微快一点——但快不了多少!

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

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

和其他人一样,我相信进行更大的读取会在一定程度上提高应用程序的性能,但不要期待奇迹,I/O已经在操作系统层进行了缓冲,因此您只会通过减少过多读取调用的开销来获得好处。一次性读取整个文件是很危险的,除非您知道输入文件的最大可能大小。最合理的方法是将文件分成大块读取。

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

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

决定一个好的块大小必须根据你想要实现的目标来完成。

说实话,在我攻读学位期间研究了一段时间的效率之后,我得出了关于你的问题的结论:这取决于这个文件被读取的频率。如果你只读一次,那么就把它读完,因为这样可以腾出时间来处理其他任务。还有一件事要记住,文件是否稍后会被编辑并需要更新(比如只读取更新的部分?)如果是这样,您可能需要设置一个标记来识别从哪里读取(然后再一次更新多长时间?)但是,如果它是一次性作业,则可以继续将其作为一个整体读取,只要您不需要为文件中的某些文字创建令牌。

一个因素是你将要读取多少数据,因此程序最初运行需要多长时间,也就是说,是否在性能上有任何好处。

请参阅答案中引用的书籍,以获得关于思考软件性能的一些好的、通用的建议。

(我知道你在理论上想要一个答案,但是当你有有限的时间时,何时担心性能也很重要。)