回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我最近突发奇想,用<code>timeit</code>测试了这两种方法,看看哪种评估方法更快:</p>
<pre><code>import timeit
"""Test method returns True if either argument is falsey, else False."""
def and_chk((a, b)):
if not (a and b):
return True
return False
def not_or_chk((a, b)):
if not a or not b:
return True
return False
</code></pre>
<p>…结果是:</p>
^{pr2}$
<p>效率的差异在1%到9%之间,总是有利于<code>if not (a and b)</code>,这与我可能预期的相反,因为我知道<code>if not a or not b</code>将按顺序计算其项(<code>if not a</code>,然后<code>if not b</code>),一旦遇到真正的表达式(并且没有<code>and</code>子句),它将运行<code>if</code>块。相反,<code>and_chk</code>方法需要计算<em>两个</em>子句,然后才能将任何结果返回给包装它的<code>if not..</code>。在</p>
<p>然而,时间安排的结果却否定了这种理解。那么,如何计算<code>if</code>条件?我完全意识到这样的微观优化程度实际上是毫无意义的。我只想了解Python是怎么做的。在</p>
<hr/>
<p>为了完成,这是我如何设置<code>timeit</code>。。。在</p>
<pre><code>cyc = 1111111
bothFalse_and = iter([(0,0)] * cyc)
zeroTrue_and = iter([(1,0)] * cyc)
oneTrue_and = iter([(0,1)] * cyc)
bothTrue_and = iter([(1,1)] * cyc)
bothFalse_notor = iter([(0,0)] * cyc)
zeroTrue_notor = iter([(1,0)] * cyc)
oneTrue_notor = iter([(0,1)] * cyc)
bothTrue_notor = iter([(1,1)] * cyc)
time_bothFalse_and = timeit.Timer('and_chk(next(tups))', 'from __main__ import bothFalse_and as tups, and_chk')
time_zeroTrue_and = timeit.Timer('and_chk(next(tups))', 'from __main__ import zeroTrue_and as tups, and_chk')
time_oneTrue_and = timeit.Timer('and_chk(next(tups))', 'from __main__ import oneTrue_and as tups, and_chk')
time_bothTrue_and = timeit.Timer('and_chk(next(tups))', 'from __main__ import bothTrue_and as tups, and_chk')
time_bothFalse_notor = timeit.Timer('not_or_chk(next(tups))', 'from __main__ import bothFalse_notor as tups, not_or_chk')
time_zeroTrue_notor = timeit.Timer('not_or_chk(next(tups))', 'from __main__ import zeroTrue_notor as tups, not_or_chk')
time_oneTrue_notor = timeit.Timer('not_or_chk(next(tups))', 'from __main__ import oneTrue_notor as tups, not_or_chk')
time_bothTrue_notor = timeit.Timer('not_or_chk(next(tups))', 'from __main__ import bothTrue_notor as tups, not_or_chk')
</code></pre>
<p>…然后用<code>.timeit(cyc)</code>运行每个<code>timeit.Timer(..)</code>函数,以获得发布的结果。在</p>