读取模式匹配的文件搜索的最快方法

时间:2016-07-01 20:29:00

标签: python grep

我制作了一个python脚本来分析日志。我有一个观察要分享,还有两个问题要问。

当我使用gzip.open打开每个文件并遍历每一行时,只需要大约200秒来浏览所有行和文件。

Row

如果使用RowData.xmlaccessibilityIdentifier来完成工作,则大约需要50秒。

with gzip.open(file) as fp:
    for line in fp:
          pass

性能差异太大而不容忽视。有没有更好的方法来缩小差距?

我还注意到zcat模块已被grep模块淘汰,它似乎总是创建一个临时文件。但它不方便,如果不能从python脚本运行的地方创建临时文件怎么办?有什么建议吗?

1 个答案:

答案 0 :(得分:1)

' grep的'包含十年的优化,并且在任何编程语言中重新实现它,而不仅仅是Python,将会更慢。 * 1

因此,如果速度对您很重要,那么您的呼叫技巧就会变得非常重要。直接可能是要走的路。要使用' subprocess'执行此操作,而不必编写任何临时文件,请使用' subprocess.PIPE'机构:

from subprocess import Popen, PIPE

COMMAND = 'zcat file* | grep oldconfig'
process = Popen(COMMAND, shell=True, stderr=PIPE, stdout=PIPE)
output, errors = process.communicate()
assert process.returncode == 0, process.returncode
assert errors == '', errors
print('{} lines match'.format(len(output.splitlines())))

这适用于Python3.5。我最近避免使用在子进程之上添加的任何更高级别的接口,因此它也适用于旧版本的Python。

(* 1例如,即使是空的' for'循环,正如您在问题中所示,grep可能仍然更快,因为它不会逐行读取输入相反,它确定了它可以通过文件向前搜索的最大字符数,完全忽略换行符,在每次搜索后读取一个字符,搜索可能与正则表达式的任何部分匹配的字符。只有找到匹配才会看到它在匹配周围的字符处,查看正则表达式的其余部分是否匹配以及是否存在相应的换行符。最重要的是,它动态生成硬编码的代码以检查与给定正则表达式的匹配,这意味着它执行大约3 x86它检查的每个输入字节的指令,并且它完全跳过检查大多数输入字节)