我有几个我想阅读的日志文件。不失一般性,假设日志文件处理完成如下:
def process(infilepath):
answer = 0
with open (infilepath) as infile:
for line in infile:
if line.startswith(someStr):
answer += 1
return answer
由于我有很多日志文件,我想在这个问题上抛出多处理(我的第一个错误:我应该使用多线程;有人请告诉我原因)
在这样做的时候,我想到任何形式的并行处理在这里都应该没用,因为我受到硬盘上只有一个读头的限制,因此,只有一个文件可能是一次读。实际上,在这种推理下,由于可以同时请求来自不同文件的行的事实,读头可能需要不时地移动,导致多过程方法比串行方法慢。所以我决定回到一个过程来阅读我的日志文件。
有趣的是,我注意到我确实得到了小文件(< = 40KB)的加速,并且只有大文件(> = 445MB)才能发现预期的减速。
这让我相信python可能会读取块中的文件,这些块的大小超过我一次请求的一行。
Q1:那么引擎盖下的文件阅读机制是什么?
Q2:优化从传统硬盘中读取文件的最佳方法是什么?
技术规格:
答案 0 :(得分:2)
观察到的行为是:
的结果根据操作系统和读取块大小,整个文件可以放入一个块中,这是在单个读取命令中读取的块。这就是为什么更容易阅读较小的文件
必须在block size
块中读取较大的文件(filesize>读取块大小)。因此,当对若干文件中的每一个请求读取时(由于多处理),针必须移动到HDD的不同扇区(对应于文件所在的位置)。这种重复的运动做了两件事:
如果在一大块行上执行的计算在读头可以提供来自同一文件的下一行行之前完成,则连续读取同一文件之间的时间很重要,该过程只是等待直到另一行可用的行。这是减速的一个来源
抛出读预测器是不好的,原因与why throwing off the branch predictor is bad几乎相同。
由于这两个问题的综合影响,并行处理许多大文件比串行处理它们要慢。当然,在处理blockSize
许多行完成numProcesses * blockSize
可以从HDD中读出许多行之前更是如此
答案 1 :(得分:1)
另一个想法是分析你的代码
try:
import cProfile as profile
except ImportError:
import profile
profile.run("process()")
答案 2 :(得分:0)
这是使用内存映射文件的示例
import mmap
with open("hello.txt", "r+b") as f:
mapf = mmap.mmap(f.fileno(), 0)
print(mapf.readline())
mapf.close()
enter code here