Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.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 IO吗?_Python_Linux_Performance_Text Files - Fatal编程技术网

有可能加速python IO吗?

有可能加速python IO吗?,python,linux,performance,text-files,Python,Linux,Performance,Text Files,考虑一下这个python程序: import sys lc = 0 for line in open(sys.argv[1]): lc = lc + 1 print lc, sys.argv[1] 在我的6GB文本文件上运行它,大约需要2分钟 问题:有可能跑得更快吗? 请注意,以下情况需要相同的时间: wc -l myfile.txt 所以,我怀疑我的问题的答案只是一个简单的“不” 还要注意,我真正的程序所做的事情比仅仅计算行数更有趣,因此请给出一个一般性的答案,而不是行数技巧(

考虑一下这个python程序:

import sys

lc = 0
for line in open(sys.argv[1]):
    lc = lc + 1

print lc, sys.argv[1]
在我的6GB文本文件上运行它,大约需要2分钟

问题:有可能跑得更快吗?

请注意,以下情况需要相同的时间:

wc -l myfile.txt
所以,我怀疑我的问题的答案只是一个简单的“不”

还要注意,我真正的程序所做的事情比仅仅计算行数更有趣,因此请给出一个一般性的答案,而不是行数技巧(比如在文件中保留行数元数据)

PS:我在这个问题上加了“linux”标签,因为我只对linux特定的答案感兴趣。如果你有操作系统不可知论,或者其他操作系统的答案,请随意给出

另请参见普通的“否”。

您几乎已经达到了最大磁盘速度


我的意思是,您可以读取文件,或者读取二进制块,然后使用
.count('\n')
或其他方法。但这不太可能带来重大改进。

如果假设磁盘可以读取60MB/s,则需要6000/60=100秒,即1分40秒。我不认为您可以更快,因为磁盘是瓶颈。

正如其他人所说:“不”

你几乎所有的时间都在等待IO。如果这是您需要多次执行的操作,并且您有一台具有大量ram的机器,那么您可以将该文件保存在内存中。如果您的机器有16GB的ram,那么在/dev/shm上可以使用8GB

另一种选择:
如果您有多台机器,这个问题对于并行化来说是微不足道的。在多台机器之间拆分it,每台机器都计算其换行数,并添加结果。

您的磁盘读取速度不能超过最大磁盘读取速度

为了达到最大磁盘速度,您可以使用以下两个技巧:

  • 用大缓冲区读取文件。这可以“手动”编码,也可以简单地使用io.BufferedReader(python2.6+中提供)
  • 在另一个线程中并行计算换行符

  • 请注意,Python I/O是在C中实现的,因此没有多少运气可以进一步加快它的速度。

    用硬件解决这个问题。

    正如gs指出的,您的瓶颈是硬盘传输速率。所以,不,你不能用更好的算法来提高你的时间,但你可以买一个更快的硬盘

    编辑:gs的另一个优点;您还可以使用配置来提高速度。这可以使用或软件(例如,等)来完成


    控制方程

    (转账金额)/(转账利率)=(转账时间)

    (6000 MB)/(60 MB/s)=100秒

    (6000 MB)/(125 MB/s)=48秒


    硬件解决方案

    被认为是企业环境中最快的解决方案,“将于2009年4月推出”

    或者您也可以查看WD Velociraptor硬盘(10000 rpm)


    另外,我听说希捷是一个不错的选择(15000转/分,持续125MB/s的传输速率)。

    诀窍不是让电子移动得更快(这很难做到),而是让每单位时间做更多的工作

    首先,确保您的6GB文件读取是I/O绑定的,而不是CPU绑定的

    如果是I/O绑定,请考虑“扇出”设计模式。

    • 父进程产生一堆子进程

    • 父级读取6Gb文件,并通过写入子级的STDIN管道将行输出给子级。6GB的读取时间将保持不变。行处理应尽可能少地涉及父处理。应使用非常简单的过滤器或计数

      管道是内存中用于通信的通道。它是一个与读写器共享的缓冲区

    • 每个孩子从STDIN中读取一行,并做适当的工作。每个孩子可能都应该编写一个简单的磁盘文件,其中包含最终(总结、减少)结果。稍后,可以合并这些文件中的结果


    2分钟听起来可以读取整个6gb文件。对于算法或操作系统来说,没有什么可以加快速度的。我认为你有两个选择:

  • 花钱解决这个问题,得到更好的硬件。如果这个项目适合你的工作,可能是最好的选择

  • 不要读取整个文件。我不知道你想用这些数据做什么,所以也许你别无选择,只能阅读整件事。另一方面,如果您正在扫描整个文件以查找某个特定的内容,那么在开始时在其中放入一些元数据可能会有所帮助


  • 这里有一个非常类似的讨论:这里的大部分时间可能都花在等待磁盘上。请参阅关于使用
    posix_fadvise(2)
    来回答您的后续问题。我来晚了,但是对于大文件,“sed-n'$=”filename”比“wc-l”快-我不知道在另一个线程中如何加快换行计数。这只会让事情变慢。等待线程不会让你等待得更快。通常你是对的。但是,在这种情况下,从文件读取的线程将等待I/O,而另一个线程则解析换行符。这样,读线程就不会等待解析器线程在后续读取之间解析换行符。我接受这个答案,即使在这种情况下,它不值得付出努力,因为每行的作业量非常低,而且我已经在以hw最大速度运行。更多细节请参见后续问题。我同意nosklo的观点。我认为增量如此之快以至于与此无关,而另一个线程甚至可以使这样的事情变慢。此外,默认情况下,for循环已经在python中进行了缓冲。我怀疑使用BufferedReader使缓冲区变大会有帮助。你计算中的20是从哪里来的?你是说6000/60=100?60不是20,对吗?我首先想用20MB/s计算,但后来我想