Python:为什么 `not not x` 比 `bool(x)` 快两倍以上
Python: Why is `not not x` more than twice as fast as `bool(x)`
考虑一下:
>>> from timeit import timeit
>>> timeit('x = 1; t = bool(x)')
0.08783805199999506
>>> timeit('x = 1; t = not not x')
0.018457599000015534
现在我知道函数调用通常会给您带来开销,但通常情况下,小的常见情况(例如这个)由编译器和解释器优化。
那么这里发生了什么?
typically, the small common cases (such as this one) are optimized by compilers and interpreters
也许在带有 JIT 的解释器中,但 Python 的参考实现没有。它实际上是在当前全局命名空间字典中执行 bool
名称的哈希查找,没有找到它,回退到内置命名空间字典中的哈希查找,找到 bool
类型,并执行 __new__
和 __init__
.
相比之下,not not x
可以跳过所有这些。它仍然需要执行 x
的 convert-to-boolean 挂钩,但 bool(x)
也必须这样做。 not not x
必须做的事情 bool(x)
不是两个否定和一个将 bool 转换为 bool 的操作,但这在 C 级别更直接(并且 bool 有一条快速路径-to-bool noop 转换)。
考虑一下:
>>> from timeit import timeit
>>> timeit('x = 1; t = bool(x)')
0.08783805199999506
>>> timeit('x = 1; t = not not x')
0.018457599000015534
现在我知道函数调用通常会给您带来开销,但通常情况下,小的常见情况(例如这个)由编译器和解释器优化。
那么这里发生了什么?
typically, the small common cases (such as this one) are optimized by compilers and interpreters
也许在带有 JIT 的解释器中,但 Python 的参考实现没有。它实际上是在当前全局命名空间字典中执行 bool
名称的哈希查找,没有找到它,回退到内置命名空间字典中的哈希查找,找到 bool
类型,并执行 __new__
和 __init__
.
相比之下,not not x
可以跳过所有这些。它仍然需要执行 x
的 convert-to-boolean 挂钩,但 bool(x)
也必须这样做。 not not x
必须做的事情 bool(x)
不是两个否定和一个将 bool 转换为 bool 的操作,但这在 C 级别更直接(并且 bool 有一条快速路径-to-bool noop 转换)。