【问题标题】:In python why is explicit bool much slower than implicit在 python 中,为什么显式 bool 比隐式慢得多
【发布时间】:2018-09-19 00:16:07
【问题描述】:

给定以下三个函数

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 调用 bool() 而不是从 c(我假设 if 确实如此)导致性能差异?

【问题讨论】:

  • 因为内置...甚至xlen(x) != 0x != [] 更快。 (在某些问题中)
  • c += bool(a)呢?)
  • 我相信 bool() 实际上会实例化一个 bool 类对象,然后进行会导致性能下降的检查
  • bool() 是一个类或类型构造函数,它是通用的,没有针对这个任务进行优化,相关:stackoverflow.com/questions/49009870/…

标签: python performance python-3.6


【解决方案1】:

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

使用bool Python 不能直接去构造一个新的bool 对象。它必须进行查找才能找到bool 的确切附加内容;然后它检查它是否可以调用,解析它的参数并 然后调用它。

使用if _a 等结构具有明确的含义。如果加载的值具有真实值,它会通过特定的 OPCODE(此处为POP_JUMP_IF_FALSE)和checks。可以跳过的箍要少得多。

bool 调用same function 来检查提供的值是True 还是False,它只是需要更长的行程才能到达那里。

【讨论】:

    【解决方案2】:

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

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

    v3 需要在 Python 级别实际调用 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 的速度。

    【讨论】:

      猜你喜欢
      • 2012-10-19
      • 1970-01-01
      • 2012-09-13
      • 1970-01-01
      • 1970-01-01
      • 2015-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多