我有一个python脚本,它逐行读取文件,看看每一行是否与正则表达式匹配.
我想在搜索之前使用内存映射文件来提高该脚本的性能.我查看了mmap示例:http://docs.python.org/2/library/mmap.html
我的问题是,当我的机器内存太大(15GB)时,我怎么能mmap文件(4GB)
我读了这样的文件:
fi = open(log_file, 'r', buffering=10*1024*1024)
for line in fi:
//do somemthong
fi.close()
Run Code Online (Sandbox Code Playgroud)
由于我将缓冲区设置为10MB,就性能而言,是否与我mmap 10MB的文件相同?
谢谢.
aba*_*ert 30
首先,你的机器的内存是无关紧要的.它与您的流程地址空间的大小相关.使用32位Python,这将低于4GB.使用64位Python,它将绰绰有余.
这样做的原因mmap不是将文件映射到物理内存,而是映射到虚拟内存.一个mmapPED文件变得就像为你的程序的特殊的交换文件.考虑到这一点可能会有点复杂,但上面的维基百科链接应该会有所帮助.
所以,第一个答案是"使用64位Python".但显然这可能不适用于您的情况.
显而易见的替代方案是在第一个1GB中进行映射,搜索,取消映射,在下一个1GB中映射,等等.执行此操作的方法是指定方法的参数length和offset参数mmap.例如:
m = mmap.mmap(f.fileno(), length=1024*1024*1024, offset=1536*1024*1024)
Run Code Online (Sandbox Code Playgroud)
但是,您正在搜索的正则表达式可以在前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过read或read+ lseek如果你使用的madvise,但在这里,这是不相关的.)但实际上,这只是一个猜测.
使用最引人注目的原因mmap通常是它比read基于代码的代码更简单,而不是它更快.当你不得不使用窗口时mmap,当你不需要进行任何搜索时read,这不那么引人注目,但是,如果你尝试双向编写代码,我希望你的mmap代码会有点结束更具可读性.(特别是如果你试图从显而易见的read解决方案中优化缓冲区副本.)