我正在尝试在Python中使用timeit模块(编辑:我们正在使用Python 3),以便在几个不同的代码流之间进行选择。在我们的代码中,我们有一系列if语句来测试字符串中字符代码的存在性,并且如果存在,则像这样替换:
if "<substring>" in str_var:
str_var = str_var.replace("<substring>", "<new_substring>")
我们会针对不同的子字符串多次执行此操作。我们正在考虑使用这种方法,或者仅使用替换功能,如下所示:
str_var = str_var.replace("<substring>", "<new_substring>")
我们尝试使用timeit来确定哪个更快。如果上面的第一个代码块是"stmt1",第二个是"stmt2",并且我们的设置字符串如下:
str_var = '<string><substring><more_string>',
我们的timeit语句将如下所示:
我们的timeit语句将如下所示:
timeit.timeit(stmt=stmt1, setup=setup)
并且
timeit.timeit(stmt=stmt2, setup=setup)
现在,仅仅像这样在我们的两台笔记本电脑上运行它(相同的硬件,类似的处理负载),stmt1(带有if语句的语句)即使在多次运行后也比stmt2更快(0.03秒对于大约0.25秒)。
然而,如果我们定义函数来执行这两个操作(包括设置创建变量),如下所示:
def foo():
str_var = '<string><substring><more_string>'
if "<substring>" in str_var:
str_var = str_var.replace("<substring>", "<new_substring>")
并且
def foo2():
str_var = '<string><substring><more_string>'
str_var = str_var.replace("<substring>", "<new_substring>")
并像这样运行时间测试:
timeit.timeit("foo()", setup="from __main__ import foo")
timeit.timeit("foo2()", setup="from __main__ import foo2")
没有if语句的语句(foo2)运行更快,与未经过函数化的结果相矛盾。
我们是否忽略了Timeit的工作原理?或者Python如何处理这种情况?
编辑:这是我们实际的代码:
>>> def foo():
s = "hi 1 2 3"
s = s.replace('1','5')
>>> def foo2():
s = "hi 1 2 3"
if '1' in s:
s = s.replace('1','5')
>>> timeit.timeit(foo, "from __main__ import foo")
0.4094226634183542
>>> timeit.timeit(foo2, "from __main__ import foo2")
0.4815539780738618
与此代码相比:
>>> timeit.timeit("""s = s.replace("1","5")""", setup="s = 'hi 1 2 3'")
0.18738432400277816
>>> timeit.timeit("""if '1' in s: s = s.replace('1','5')""", setup="s = 'hi 1 2 3'")
0.02985000199987553
foo
函数方法时,if
语句方法始终在0.06左右,但非if
方法大约为0.3。当我使用foo
函数时,在这种情况下,if
语句方法大约为0.61,而非if
方法大约为0.53。(这些是使用timeit
对四种可能性进行10次计算的平均值。)我使用IPython和Python 2.7.3在一台相当快的桌面机器上。 - elyif
语句比replace
语句更短。实际上,它比单独使用replace
做更多的工作,因为if
测试是True
(所以replace
在两种情况下都运行)。if
可以节省时间的唯一方法是如果字符串不包含要替换的字符串,从而在replace
调用本身中节省一些时间,这只有在in
的时间顺序比replace
快时才成立。我不知道为什么会有很大的区别,但你在非函数与if
版本中使用了不同的要替换的字符串。 - jpmc26