<p>我刚刚通过你的Meta-SO问题注意到了这个问题:<a href="https://meta.stackoverflow.com/q/293686/4014959">Is it appropriate to share the results of my research toward solving my own minor questions?</a>。正如你在那个问题中提到的(这个问题上的一个标签表明的),这类事情属于微优化的范畴。理想情况下,人们不必担心这些细微的性能差异,正如Knuth所说,<a href="http://en.wikiquote.org/wiki/Donald_Knuth#Computer_Programming_as_an_Art_.281974.29" rel="nofollow noreferrer">premature optimization is the root of all evil</a>。但是,我想调查这些问题是有趣和有启发性的,因为它可以让您更好地了解Python是如何“隐藏”工作的。在</p>
<p><a href="https://stackoverflow.com/questions/29551438/why-is-if-not-a-and-b-faster-than-if-not-a-or-not-b#comment47254379_29551438">Mephy's comment</a>提示我查看您的函数的<code>if</code>版本的时间差异。结果很有趣,伊莫。我也借此机会简化了你的测试程序。在</p>
<pre><code>#!/usr/bin/env python
''' Do timeit tests on various implementations of NAND
NAND returns True if either argument is falsey, else False.
From https://stackoverflow.com/q/29551438/4014959
Written by PM 2Ring 2015.04.09
'''
from timeit import Timer
import dis
def and_chk(a, b):
return not (a and b)
def and_chk_if(a, b):
if not (a and b):
return True
else:
return False
def not_or_chk(a, b):
return not a or not b
def not_or_chk_if(a, b):
if not a or not b:
return True
else:
return False
#All the functions
funcs = (
and_chk,
and_chk_if,
not_or_chk,
not_or_chk_if,
)
#Argument tuples to test the functions with
bools = (0, 1)
bool_tups = [(u, v) for u in bools for v in bools]
def show_dis():
''' Show the disassembly for each function '''
print 'Disassembly'
for func in funcs:
fname = func.func_name
print '\n%s' % fname
dis.dis(func)
print
def verify():
''' Verify that the functions actually perform as intended '''
print 'Verifying...'
for func in funcs:
fname = func.func_name
print '\n%s' % fname
for args in bool_tups:
print args, func(*args)
print
def time_test(loops, reps):
''' Print timing stats for all the functions '''
print 'Timing tests\nLoops = %d, Repetitions = %d' % (loops, reps)
for func in funcs:
fname = func.func_name
print '\n%s' % fname
setup = 'from __main__ import %s' % fname
for args in bool_tups:
t = Timer('%s%s' % (fname, args), setup)
r = t.repeat(reps, loops)
r.sort()
print args, r
show_dis()
verify()
time_test(loops=520000, reps=3)
</code></pre>
<p><strong>输出</strong></p>
^{pr2}$
<p>这些计时是在运行mepis11(Debian系列Linux发行版)的2Ghzpentium4(单核32位)上使用python2.6.6执行的。在</p>
<p>您会注意到,我避免了使用<code>next(tups)</code>策略来获取每个函数调用的参数,而是直接将参数作为常量传递。执行<code>next(tups)</code><em>所花的时间应该是相当恒定的,但是最好在实际情况下消除这样的开销,以便报告的时间度量更准确地反映我们真正感兴趣的代码的性能。在</p>
<p>此外,通常要重复几次定时循环,取最小值;FWIW,我通常重复3到5次。从<a href="https://docs.python.org/2/library/timeit.html" rel="nofollow noreferrer">timeit docs</a>:</p>
<blockquote>
<p><strong>Note</strong></p>
<p>It’s tempting to calculate mean and standard deviation from the result
vector and report these. However, this is not very useful. In a
typical case, the lowest value gives a lower bound for how fast your
machine can run the given code snippet; higher values in the result
vector are typically not caused by variability in Python’s speed, but
by other processes interfering with your timing accuracy. So the min()
of the result is probably the only number you should be interested in.
After that, you should look at the entire vector and apply common
sense rather than statistics.</p>
</blockquote>
<p>您的Meta post说您希望对其他微优化实验执行报告,因此您可能有兴趣看看我几个月前发布的一些代码,这些代码对<a href="https://stackoverflow.com/a/28477818/4014959">factorial</a>函数的各种实现进行时间测试。在</p>