首先,您机器的内存无关紧要。这是相关的进程地址空间的大小。对于 32 位 Python,这将低于 4GB。使用 64 位 Python 就绰绰有余了。
这样做的原因mmap
不是将文件映射到物理内存,而是映射到虚拟内存。mmap
ped 文件就像您的程序的特殊交换文件一样。考虑这一点可能会有点复杂,但上面的维基百科链接应该会有所帮助。
所以,第一个答案是“使用 64 位 Python”。但显然这可能不适用于您的情况。
显而易见的替代方法是在前 1GB 中进行映射,然后对其进行搜索、取消映射、在下一个 1GB 中进行映射,等等。执行此操作的方法是为方法指定length
andoffset
参数mmap
。例如:
m = mmap.mmap(f.fileno(), length=1024*1024*1024, offset=1536*1024*1024)
但是,您正在搜索的正则表达式可以在前 1GB 中找到一半,在第二个中找到一半。因此,您需要使用窗口化——在前 1GB 中映射、搜索、取消映射,然后在部分重叠的 1GB 中映射,等等。
问题是,您需要多少重叠?如果您知道匹配的最大可能大小,则不需要更多。如果你不知道……好吧,如果不破坏你的正则表达式,就没有办法真正解决问题——如果这不是很明显,想象一下你怎么可能在一个 1GB 的窗口中找到一个 2GB 的匹配。
回答您的后续问题:
由于我将缓冲区设置为10MB,就性能而言,它与我mmap 10MB的文件一样吗?
与任何性能问题一样,如果它真的很重要,您需要对其进行测试,如果不重要,请不要担心。
如果你想让我猜:我认为mmap
这里可能更快,但只是因为(正如 JF Sebastian 暗示的那样)循环和调用re.match
128K 次可能会导致你的代码受 CPU 限制而不是 IO 限制。但是您可以在没有 的情况下优化它mmap
,只需使用read
. 那么,会mmap
比read
? 考虑到所涉及的大小,我希望mmap
在旧 Unix 平台上的性能会快得多,在现代 Unix 平台上大致相同,而在 Windows 上会慢一些。(如果您使用,您仍然可以从mmap
overread
或read
+中获得巨大的性能优势,但这与这里无关。)但实际上,这只是一个猜测。lseek
madvise
最令人信服的使用理由mmap
通常是它比read
基于 - 的代码更简单,而不是它更快。当您甚至必须使用窗口时mmap
,并且当您不需要进行任何搜索时read
,这就不那么引人注目了,但是,如果您尝试以两种方式编写代码,我希望您的mmap
代码最终会有点更具可读性。(特别是如果您尝试从明显的read
解决方案中优化缓冲区副本。)