考虑这个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特定的答案感兴趣。如果有的话,请随意提供与操作系统无关的内容,甚至是其他操作系统的答案。答案 0 :(得分:12)
在问题上抛出硬件。
正如gs所指出的,你的瓶颈是硬盘传输率。所以,不,你不能使用更好的算法来改善你的时间,但你可以购买更快的硬盘。
编辑: gs的另一个好处;您还可以使用RAID配置来提高速度。这可以使用hardware或软件(例如OS X,Linux,Windows Server等)来完成。
管理公式
(Amount to transfer) / (transfer rate) = (time to transfer)
(6000 MB) / (60 MB/s) = 100 seconds
(6000 MB) / (125 MB/s) = 48 seconds
硬件解决方案
The ioDrive Duo被认为是企业环境中最快的解决方案,“将于2009年4月上市”。
或者您可以查看WD Velociraptor硬盘(10,000 rpm)。
另外,我听说Seagate Cheetah是一个不错的选择(转速为15,000 rpm,传输速率为125MB / s)。
答案 1 :(得分:8)
诀窍不是让电子移动得更快(这很难),而是每单位时间完成更多的工作。
首先,确保您的6GB文件读取是I / O绑定,而不是CPU绑定。
如果它受I / O限制,请考虑“扇出”设计模式。
父进程会产生一群孩子。
父级读取6Gb文件,并通过写入STDIN管道将子行传递给子级。 6GB的读取时间将保持不变。行处理应尽可能少地处理父处理。应该使用非常简单的过滤器或计数。
管道是用于通信的内存中通道。它是一个带读者和作者的共享缓冲区。
每个孩子从STDIN中读取一行,并做适当的工作。每个孩子应该写一个简单的磁盘文件,其中包含最终(汇总,减少)结果。稍后,可以合并这些文件中的结果。
答案 2 :(得分:5)
答案 3 :(得分:4)
如果您认为磁盘可以读取60MB / s,则需要6000/60 = 100秒,即1分40秒。我不认为你可以更快,因为磁盘是瓶颈。
答案 4 :(得分:4)
您的速度不能超过最大磁盘读取速度。
为了达到最大磁盘速度,您可以使用以下两个提示:
答案 5 :(得分:1)
正如其他人所说 - “不”
几乎所有的时间都花在等待IO上。如果这是您需要多次执行的操作,和您拥有一台有大量内存的计算机,您可以将该文件保留在内存中。如果你的机器有16GB的内存,你可以在/ dev / shm下使用8GB。
另一种选择: 如果您有多台计算机,这个问题在并行化方面是微不足道的。在多台机器之间拆分它,每台机器都计算它们的换行符,并添加结果。
答案 6 :(得分:1)
2分钟听起来有权阅读整个6gb文件。你可以对算法或操作系统做些什么来加快速度。我认为你有两个选择:
为问题投入资金并获得更好的硬件。如果这个项目适合你的工作,可能是最好的选择。
不要读取整个文件。我不知道你要对数据做什么,所以也许你没有任何选择,只能阅读整个事情。另一方面,如果您正在扫描整个文件中的某个特定内容,那么在开始时将一些元数据放在那里会有所帮助。
答案 7 :(得分:0)
请注意,Python I / O是用C实现的,所以没有太多运气可以进一步加快它的速度。