Python 并行磁盘I/O
我有几个日志文件,我想读。在不丧失通用性的情况下,假设日志文件处理如下所示:Python 并行磁盘I/O,python,macos,python-3.3,disk-io,Python,Macos,Python 3.3,Disk Io,我有几个日志文件,我想读。在不丧失通用性的情况下,假设日志文件处理如下所示: def process(infilepath): answer = 0 with open (infilepath) as infile: for line in infile: if line.startswith(someStr): answer += 1 return answer 因为我有很多日志文件,所以我想在这
def process(infilepath):
answer = 0
with open (infilepath) as infile:
for line in infile:
if line.startswith(someStr):
answer += 1
return answer
因为我有很多日志文件,所以我想在这个问题上使用多处理(我的第一个错误:我应该使用多线程;有人请告诉我为什么)
在这样做的时候,我突然想到,任何形式的并行处理在这里实际上都是无用的,因为我的硬盘上只有一个读头,因此一次只能读取一个文件。事实上,在这种推理下,由于来自不同文件的行可能被同时请求,读取头可能需要不时地显著移动,导致多过程方法比串行方法慢。所以我决定返回到单个进程来读取日志文件
但有趣的是,我注意到我确实在小文件(=445MB)中得到了加速,并且注意到了预期的速度减慢
这让我相信python可能会以块的形式读取文件,其大小一次超过我请求的一行
Q1:那么,引擎盖下的文件读取机制是什么
Q2:优化传统HDD文件读取的最佳方法是什么
技术规格:
- 蟒蛇3.3
- 5400rpm常规硬盘
- MacOSX10.9.2(小牛)
- 下面是一个使用内存映射文件的示例
import mmap
with open("hello.txt", "r+b") as f:
mapf = mmap.mmap(f.fileno(), 0)
print(mapf.readline())
mapf.close()
enter code here
另一个想法是分析你的代码
try:
import cProfile as profile
except ImportError:
import profile
profile.run("process()")
观察到的行为是以下原因造成的:
块大小
块读取。因此,当请求读取多个文件中的每个文件时(由于多处理),指针必须移动到HDD的不同扇区(对应于文件所在的位置)。这种重复运动有两个作用:
由于这两个问题的共同影响,并行处理许多大文件将比串行处理慢。当然,当处理
blockSize
许多行在numProcesses*blockSize
许多行可以从硬盘读取之前完成时,这一点更为正确。s/python/操作系统/您的操作系统可能在块级别实现了至少64K字节的预读策略。在引擎盖下有缓冲IO。注意:引擎盖下的内容不是特定于python的。一个好的起点是检查C和操作系统中发生的情况。您描述的是虚拟分页系统涉及的问题,以及如何从缓冲IO中的操作系统文件中读取数据。有关更多信息,请参阅您列出的python代码中的“For line in infle”可能会产生大量开销,具体取决于它们如何实现迭代器。您是否尝试过使用不同的方法读取文件?(我讨厌5分钟编辑规则…不小心按了enter)内存映射文件在这里有什么帮助?在最初的文章中,Python只逐行读取文件,从来没有使用过太多内存(除非行太大,因为文件是以文本模式打开的,所以不应该如此)。更喜欢使用此替代解决方案编辑其他答案