Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 并行磁盘I/O_Python_Macos_Python 3.3_Disk Io - Fatal编程技术网

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只逐行读取文件,从来没有使用过太多内存(除非行太大,因为文件是以文本模式打开的,所以不应该如此)。更喜欢使用此替代解决方案编辑其他答案