[英]In python why is explicit bool much slower than implicit
Given the following three functions 鉴于以下三个功能
def v1(a):
c = 0
for a_ in a:
if a_ is not None:
c += 1
return c
def v2(a):
c = 0
for a_ in a:
if a_:
c += 1
return c
def v3(a):
c = 0
for a_ in a:
if bool(a_):
c += 1
return c
I get the following performance (I'm using python 3.6 on ubuntu 18.04) 我得到以下性能(我在ubuntu 18.04上使用python 3.6)
values = [random.choice([1, None]) for _ in range(100000)]
%timeit v1(values)
3.35 ms ± 28 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit v2(values)
2.83 ms ± 36.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit v3(values)
12.3 ms ± 59.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
The similar performance between v1
and v2
makes sense, but why is v3
so much slower given that v2
is presumably implicitly calling bool(a_)
too? v1
和v2
之间的类似性能是有道理的,但是鉴于v2
可能也是隐式调用bool(a_)
原因,为什么v3
这么慢?
Is it simply calling bool()
from python rather than from c (as I assume if
does) that's causing the difference in performance? 是否只是从python而不是c调用bool()
(我假设是的if
)会导致性能差异?
This is mainly due to Python's dynamicism and the fact that you have a Python level call. 这主要是由于Python的动态性以及您具有Python级调用的事实。
Using bool
Python can't directly go and construct a new bool
object. 使用bool
Python无法直接去构造新的bool
对象。 It has to do look ups to find what exactly is attached to bool
; 它必须进行查找以查找与bool
精确连接的内容; then it has check if it is something that can be called, parse its arguments and then call it. 然后它会检查它是否可以被调用,解析其参数然后调用它。
Using a construct such as if _a
, has a defined meaning. 使用诸如if _a
类的构造具有定义的含义。 It goes through a specific OPCODE ( POP_JUMP_IF_FALSE
here) and checks if the loaded value has a truthy value. 它通过特定的OPCODE(此处为POP_JUMP_IF_FALSE
),并检查加载的值是否具有真实值。 Way less hoops to jump through. 减少跳跃的速度。
bool
calls the same function to check if a value supplied is True
or False
, it just has a longer trip until it gets there. bool
调用相同的函数来检查提供的值是True
还是False
,它只有更长的行程才能到达。
v2
is able to evaluate the "truthiness" of a_
in the interpreter: v2
能够在解释器中评估a_
的“真实性”:
>>> dis.dis(v2)
...
11 14 LOAD_FAST 2 (a_)
16 POP_JUMP_IF_FALSE 10
...
where v3
is required to actually call bool
at the Python level: 在Python级别上需要v3
才能实际调用bool
的地方:
>>> dis.dis(v3)
...
18 14 LOAD_GLOBAL 0 (bool)
16 LOAD_FAST 2 (a_)
18 CALL_FUNCTION 1
20 POP_JUMP_IF_FALSE 10
...
The function call is what slows v3
down. 函数调用使v3
变慢。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.