在Python中使用正则表达式编译有什么好处吗?
h = re.compile('hello')
h.match('hello world')
Run Code Online (Sandbox Code Playgroud)
VS
re.match('hello', 'hello world')
Run Code Online (Sandbox Code Playgroud) 我的问题是解析日志文件并删除每行上的可变部分以便对它们进行分组.例如:
s = re.sub(r'(?i)User [_0-9A-z]+ is ', r"User .. is ", s)
s = re.sub(r'(?i)Message rejected because : (.*?) \(.+\)', r'Message rejected because : \1 (...)', s)
Run Code Online (Sandbox Code Playgroud)
我有大约120多个匹配规则,如上所述.
我在100个不同的正则表达式上连续搜索时没有发现任何性能问题.但是,当应用101个正则表达式时,会发生巨大的减速.
使用替换我的规则时会发生完全相同的行为
for a in range(100):
s = re.sub(r'(?i)caught here'+str(a)+':.+', r'( ... )', s)
Run Code Online (Sandbox Code Playgroud)
使用范围(101)代替它慢了20倍.
# range(100)
% ./dashlog.py file.bz2
== Took 2.1 seconds. ==
# range(101)
% ./dashlog.py file.bz2
== Took 47.6 seconds. ==
Run Code Online (Sandbox Code Playgroud)
为什么会发生这样的事情?有没有已知的解决方法?
(在Linux/Windows上发生在Python 2.6.6/2.7.2上.)
我正在研究Doug Hellman的"示例中的Python标准库",并且遇到了这个:
"1.3.2编译表达式包括用于将正则表达式作为文本字符串处理的模块级函数,但编译程序经常使用的表达式更有效."
我不能按照他的解释为什么会这样.他说"模块级函数维护编译表达式的缓存",并且由于"缓存大小"有限,"使用编译表达式直接避免了缓存查找开销."
如果有人可以解释或指导我解释一下,我可以更好地理解为什么编译程序经常使用的正则表达式更有效,以及这个过程实际如何工作,我将不胜感激.
假设有一个函数costly_function_a(x):
x; 和在这些条件下,x我们可以将结果存储在临时变量中,然后使用该变量进行这些计算,而不是连续两次调用函数.
现在假设有一些功能(f(x),g(x)并h(x)调用在下面的示例)costly_function_a(x),并且其中的一些功能可以调用彼此(在下面的例子中,g(x)与h(x)两个呼叫f(x)).在这种情况下,使用在重复调用以上仍结果提到的简单的方法costly_function_a(x)用相同的x(见OkayVersion下文).我确实找到了一种最小化呼叫次数的方法,但它"丑陋"(见FastVersion下文).有没有更好的方法来做到这一点?
#Dummy functions representing extremely slow code.
#The goal is to call these costly functions as rarely as possible.
def costly_function_a(x):
print("costly_function_a has been called.")
return x #Dummy operation.
def costly_function_b(x):
print("costly_function_b has been called.")
return 5.*x #Dummy operation.
#Simplest (but slowest) implementation.
class SlowVersion:
def …Run Code Online (Sandbox Code Playgroud) 我有一个执行昂贵操作的功能,经常被调用; 但是,操作只需执行一次 - 其结果可以缓存.
我尝试制作一个无限的发电机,但我没有得到我预期的结果:
>>> def g():
... result = "foo"
... while True:
... yield result
...
>>> g()
<generator object g at 0x1093db230> # why didn't it give me "foo"?
Run Code Online (Sandbox Code Playgroud)
为什么不是g发电机?
>>> g
<function g at 0x1093de488>
Run Code Online (Sandbox Code Playgroud)
编辑:如果这种方法不起作用,这很好,但我需要的东西与常规函数完全相同,如下所示:
>>> [g() for x in range(3)]
["foo", "foo", "foo"]
Run Code Online (Sandbox Code Playgroud) python ×5
regex ×3
caching ×1
compilation ×1
generator ×1
optimization ×1
performance ×1
python-2.7 ×1