ihi*_*wer 67 python regex perl performance text-processing
这是我的Perl和Python脚本,用于从大约21个日志文件进行一些简单的文本处理,每个大约300 KB到1 MB(最大)x重复5次(总共125个文件,由于日志重复5次).
Python代码(修改后使用编译re
和使用的代码re.I
)
#!/usr/bin/python
import re
import fileinput
exists_re = re.compile(r'^(.*?) INFO.*Such a record already exists', re.I)
location_re = re.compile(r'^AwbLocation (.*?) insert into', re.I)
for line in fileinput.input():
fn = fileinput.filename()
currline = line.rstrip()
mprev = exists_re.search(currline)
if(mprev):
xlogtime = mprev.group(1)
mcurr = location_re.search(currline)
if(mcurr):
print fn, xlogtime, mcurr.group(1)
Run Code Online (Sandbox Code Playgroud)
Perl代码
#!/usr/bin/perl
while (<>) {
chomp;
if (m/^(.*?) INFO.*Such a record already exists/i) {
$xlogtime = $1;
}
if (m/^AwbLocation (.*?) insert into/i) {
print "$ARGV $xlogtime $1\n";
}
}
Run Code Online (Sandbox Code Playgroud)
并且,在我的PC上,两个代码生成完全相同的10,790行结果文件.而且,这是在Cygwin的Perl和Python实现上完成的时间.
User@UserHP /cygdrive/d/tmp/Clipboard
# time /tmp/scripts/python/afs/process_file.py *log* *log* *log* *log* *log* >
summarypy.log
real 0m8.185s
user 0m8.018s
sys 0m0.092s
User@UserHP /cygdrive/d/tmp/Clipboard
# time /tmp/scripts/python/afs/process_file.pl *log* *log* *log* *log* *log* >
summarypl.log
real 0m1.481s
user 0m1.294s
sys 0m0.124s
Run Code Online (Sandbox Code Playgroud)
最初,使用Python需要10.2秒,使用Perl仅需1.9秒就可以进行简单的文本处理.
(更新)但是,在re
Python 的编译版本之后,它在Python中需要8.2秒,在Perl中需要1.5秒.Perl的速度要快得多.
有没有办法提高Python的速度或者很明显Perl将是快速的简单文本处理.
顺便说一下,这不是我为简单文本处理所做的唯一测试......而且,我制作源代码的每种不同方式,总是Perl赢得大幅度.并且,Python没有一次表现出更好的简单m/regex/
匹配和打印内容.
请不要建议使用C,C++,汇编,其他版本的Python等.
我正在寻找使用标准Python的解决方案,其内置模块与标准Perl(甚至不使用模块)进行比较.男孩,由于其可读性,我希望将Python用于我的所有任务,但是为了放弃速度,我不这么认为.
因此,请建议如何改进代码以获得与Perl相当的结果.
更新时间:2012-10-18
正如其他用户所建议的那样,Perl有它的位置,Python也有它的地位.
因此,对于这个问题,人们可以有把握地得出结论,对于数百或数千个文本文件的每行上的简单正则表达式匹配并将结果写入文件(或打印到屏幕),Perl将始终为此作业赢得性能.就这么简单.
请注意,当我说Perl在性能上获胜时...只比较标准的Perl和Python ...不要求助于一些模糊的模块(对于像我这样的普通用户而言模糊不清)而且也没有从Python调用C,C++,汇编库或者Perl.我们没有时间为简单的文本匹配工作学习所有这些额外的步骤和安装.
因此,Perl晃动文本处理和正则表达式.
Python有其他地方可以摇滚的地方.
更新2013-05-29:这里做了类似比较的优秀文章.Perl再次赢得了简单的文本匹配...有关更多详细信息,请阅读文章.
Jos*_*ght 18
这正是Perl设计的那种东西,所以它不会让我感到惊讶的是它更快.
Python代码中的一个简单优化就是预编译这些正则表达式,因此每次都不会重新编译它们.
exists_re = re.compile(r'^(.*?) INFO.*Such a record already exists')
location_re = re.compile(r'^AwbLocation (.*?) insert into')
Run Code Online (Sandbox Code Playgroud)
然后在你的循环中:
mprev = exists_re.search(currline)
Run Code Online (Sandbox Code Playgroud)
和
mcurr = location_re.search(currline)
Run Code Online (Sandbox Code Playgroud)
这本身不会神奇地使你的Python脚本与你的Perl脚本保持一致,但是在没有首先编译的情况下重复调用re是Python中的坏习惯.
ike*_*ami 14
假设:由于Python不具备的优化,Perl在不匹配的行中花费较少的时间回溯.
替换你得到什么?
^(.*?) INFO.*Such a record already exists
Run Code Online (Sandbox Code Playgroud)
同
^((?:(?! INFO).)*?) INFO.*Such a record already
Run Code Online (Sandbox Code Playgroud)
要么
^(?>(.*?) INFO).*Such a record already exists
Run Code Online (Sandbox Code Playgroud)
一般来说,所有人为的基准都是邪恶的。然而,在其他条件相同的情况下(算法方法),您可以在相对基础上进行改进。然而,应该指出的是,我不使用 Perl,所以我不能支持它。话虽如此,对于 Python,您可以尝试使用Pyrex或Cython来提高性能。或者,如果您喜欢冒险,您可以尝试通过ShedSkin将 Python 代码转换为 C++ (适用于大多数核心语言,以及一些(但不是全部)核心模块)。
不过,您可以遵循此处发布的一些提示:
http://wiki.python.org/moin/PythonSpeed/PerformanceTips