我有几个我想阅读的日志文件。不失一般性,假设日志文件处理如下:

def process(infilepath):
    answer = 0
    with open (infilepath) as infile:
        for line in infile:
            if line.startswith(someStr):
                answer += 1
    return answer

由于我有很多日志文件,我想在这个问题上抛出多处理(我的第一个错误:我可能应该使用多线程;有人请告诉我为什么)

这样做时,我想到任何形式的并行处理在这里都应该无效,因为我受到以下事实的限制:我的 HDD 上只有一个读取头,因此,一次只能读取一个文件时间。事实上,在这种推理下,由于可能同时请求来自不同文件的行,因此读取头可能需要不时地大幅移动,从而导致 multiproc 方法比串行方法慢。所以我决定回到单个进程来读取我的日志文件。

有趣的是,我注意到我确实在处理小文件 (= 445MB) 时才会注意到预期的减速。

这让我相信 python 可以分块读取文件,其大小超过我一次请求的一行。

Q1: 那么 文件读取机制 到底是什么?

Q2: 优化从 传统 HDD 读取文件的最佳方法是什么?

技术规范:
  • python3.3
  • 5400rpm 传统硬盘
  • Mac OSX 10.9.2(小牛队)
  • 最佳答案

    观察到的行为是由于:

  • 缓冲IO
  • 一种调度算法,用于决定读取 HDD 必需扇区的顺序

  • 缓冲IO

    根据操作系统和读取块大小,整个文件可能适合一个块,这是在单个读取命令中读取的内容。这就是为什么较小的文件更容易读取的原因

    调度算法

    较大的文件(文件大小 > 读取块大小),必须在 block size 块中读取。因此,当对多个文件中的每一个请求读取时(由于多处理),指针必须移动到 HDD 的不同扇区(对应于文件所在的位置)。这种重复运动有两件事:
  • 增加对同一文件的连续读取之间的时间
  • 摆脱读取扇区预测器,因为文件可能跨越多个扇区

  • 如果在读取头可以提供来自同一文件的下一个行块之前完成对一个行块执行的计算,则连续读取同一文件之间的时间很重要,该过程只是等待,直到另一个行块可用。这是放缓的原因之一

    由于与 why throwing off the branch predictor is bad 几乎相同的原因,丢弃读取预测器是不好的。

    由于这两个问题的综合影响,并行处理许多大文件会比串行处理它们慢。当然,在blockSize many lines可以从HDD读出之前处理完numProcesses * blockSize many lines时更是如此

    关于python - 并行磁盘 I/O,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22918814/

    10-12 17:53