【问题标题】:Why is True if foo else False faster then bool(foo)?如果 foo else False 比 bool(foo) 快,为什么 True if foo else False?
【发布时间】:2019-12-29 11:45:37
【问题描述】:

为什么根据 timeit.timeit 函数,代码 boolean = True if foo else False 运行速度比代码 boolean = bool(foo) 快?

if 语句如何能够比 bool 函数本身更快地确定 foo 的正确性?

为什么 bool 函数不简单地使用相同的机制?

当 bool 函数的性能可以通过不同的技术提高四倍时,它的目的是什么?

或者,是不是我误用了 timeit 函数,而 bool(foo) 实际上更快?

>>> timeit.timeit("boolean = True if foo else False", setup="foo='zon-zero'")
0.021019499999965774
>>> timeit.timeit("boolean = bool(foo)", setup="foo='zon-zero'")
0.0684856000000309
>>> timeit.timeit("boolean = True if foo else False", setup="foo=''")
0.019911300000103438
>>> timeit.timeit("boolean = bool(foo)", setup="foo=''")
0.09232059999999365

看看这些结果,True if foo else False 似乎比bool(foo) 快四到五倍。

我怀疑速度的差异是由调用函数的开销引起的,当我使用 dis 模块时似乎确实是这种情况。

>>> dis.dis("boolean = True if foo else False")
  1           0 LOAD_NAME                0 (foo)
              2 POP_JUMP_IF_FALSE        8
              4 LOAD_CONST               0 (True)
              6 JUMP_FORWARD             2 (to 10)
        >>    8 LOAD_CONST               1 (False)
        >>   10 STORE_NAME               1 (boolean)
             12 LOAD_CONST               2 (None)
             14 RETURN_VALUE
>>> dis.dis("boolean = bool(foo)")
  1           0 LOAD_NAME                0 (bool)
              2 LOAD_NAME                1 (foo)
              4 CALL_FUNCTION            1
              6 STORE_NAME               2 (boolean)
              8 LOAD_CONST               0 (None)
             10 RETURN_VALUE

根据dis模块,这两种技术的区别在于:

              2 POP_JUMP_IF_FALSE        8
              4 LOAD_CONST               0 (True)
              6 JUMP_FORWARD             2 (to 10)
        >>    8 LOAD_CONST               1 (False)

对比

              0 LOAD_NAME                1 (bool)

              4 CALL_FUNCTION            1

这使得函数调用对于像确定布尔值这样简单的事情来说看起来过于昂贵,或者 bool 函数的编写效率非常低。 但这实际上让我想知道为什么有人会在 bool 函数这么慢的时候使用它,以及为什么 bool 函数甚至在 python 内部似乎没有使用它时仍然存在。

那么,bool 函数的速度慢是因为它的编写效率低下,还是因为函数开销,还是因为其他原因?

当有更快且同样清晰的替代方案可用时,为什么有人会使用 bool 函数?

【问题讨论】:

    标签: python optimization


    【解决方案1】:

    根据 Python 文档:

    类 bool( [ x ] ) 返回一个布尔值,即 True 或 False 之一。 x 使用标准真值测试转换 程序。如果 x 为假或省略,则返回 False;否则返回 True。布尔类是一个 int 的子类(请参阅数值类型 - int、float、complex)。它不能被进一步细分。这只是 实例是 False 和 True

    因此,当您直接使用对象本身(如 foo)时,解释器使用其 foo.__bool__ 属性。但是 bool 函数是一个包装器,它再次调用foo.__bool__ 正如您所说,调用该函数使其变得昂贵。 而 bool 的使用是,在某些情况下,你需要一个对象的布尔值,并且需要通过一个变量来引用它。

    x = bool(my_object)x = my_object 不起作用。 在这里它很有用。 有时 bool(foo) 更具可读性,您可以忽略小的时间滞后。 您可能也有兴趣知道 x = {}x = dict()

    找出原因... :)

    【讨论】:

    • 我明白了,但我有理由选择使用bool(foo) 而不是True if foo else False。当 timeit.timeit 声称 True if foo else False 更快?
    • 我也在上面回答过。在某些情况下,您需要获取对象的布尔值。请注意,布尔值不仅限于 if-else 或循环块。它们也有其他用途。拿简单的上下文来说,需要打印一个对象的布尔值,不能写print(if object),正确的方法是使用print(bool(object))
    • bool(foo) 更短且更易读,如果这段代码不是您程序中的瓶颈,则更可取。速度不是一切。
    • @chepner 是的,这是另一种用途。本来想加的,但是忘记了。谢谢
    猜你喜欢
    • 1970-01-01
    • 2012-06-12
    • 1970-01-01
    • 2013-06-27
    • 2013-11-01
    • 2015-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多