繁体   English   中英

在python中为什么显式布尔比隐式慢得多

[英]In python why is explicit bool much slower than implicit

鉴于以下三个功能

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

我得到以下性能(我在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)

v1v2之间的类似性能是有道理的,但是鉴于v2可能也是隐式调用bool(a_)原因,为什么v3这么慢?

是否只是从python而不是c调用bool() (我假设是的if )会导致性能差异?

这主要是由于Python的动态性以及您具有Python级调用的事实。

使用bool Python无法直接去构造新的bool对象。 它必须进行查找以查找与bool精确连接的内容; 然后它会检查它是否可以被调用,解析其参数然后调用它。

使用诸如if _a类的构造具有定义的含义。 它通过特定的OPCODE(此处为POP_JUMP_IF_FALSE ),并检查加载的值是否具有真实值。 减少跳跃的速度。

bool调用相同的函数来检查提供的值是True还是False ,它只有更长的行程才能到达。

v2能够解释器中评估a_的“真实性”:

 >>> dis.dis(v2)
 ...
 11          14 LOAD_FAST                2 (a_)
             16 POP_JUMP_IF_FALSE       10
 ...

在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
...

函数调用使v3变慢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM