【问题标题】:Performance of ternary operator vs if-else statement三元运算符与 if-else 语句的性能
【发布时间】:2017-11-19 20:34:54
【问题描述】:

注意:这个问题确实已经为许多其他语言提供了答案。 但是,我找不到 Python 的答案,所以不要标记为重复。

if-else 语句和 Python 中的三元运算符在性能上有区别吗?

【问题讨论】:

  • 只要使用你觉得让代码更易读的那个就行。如果您曾经处于真正可能产生影响的热循环中,请以两种方式对其进行编码并在实际代码的上下文中测量性能。可能还有其他更重要的因素,例如您使用的算法。

标签: python if-statement ternary-operator


【解决方案1】:

这是我在 IPython 7.2.0 中的测试(它有 %timeit,这是一种内置的计时方法,可以非常容易地测量执行情况。默认情况下,它每次运行 7 次,循环次数为 1 亿次,所以结果通常应该是有效的)由运行 CPython 3.7.2 x64 的 PyCharm 2018.3.4 Community Edition x64 使用。操作系统是 Window$ 10.0.17134 Enterprise x64:

##The 1st 2 are without quoting the statement to see how it affects the test.
%timeit 3 if True else 8
14.7 ns ± 0.319 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

%timeit 3 if False else 8
18.1 ns ± 0.211 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

##----------------------------------------------------------------------------

%timeit 'if True:\n    3\nelse:\n    8'
8.67 ns ± 0.314 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

%timeit 'if False:\n    3\nelse:\n    8'
8.4 ns ± 0.0598 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

##----------------------------------------------------------------------------

##The last 2 are with quoting the statement.
%timeit '3 if True else 8'
8.73 ns ± 0.256 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

%timeit '3 if False else 8'
9.37 ns ± 0.215 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

我认为数字代表了陈述。真的很可惜,因为我喜欢三元运算。

但是,三元运算仍然绝对有用,尤其是在覆盖函数调用参数中的所有可能性会产生大量重复代码的情况下,我非常讨厌。

【讨论】:

    【解决方案2】:

    从 Python 3.6.1 上的一些测试来看,完整的语句似乎更快。

    我的结果:

    >>> timeit.timeit("""3 if True else 8""")
    0.012174860001323395
    >>> timeit.timeit("""3 if False else 8""")
    0.019092951000857283
    >>> timeit.timeit("""if True:
    ...     3
    ... else:
    ...     8""")
    0.009110345999943092
    >>> timeit.timeit("""if False:
    ...     3
    ... else:
    ...     8""")
    0.00877297099941643
    

    【讨论】:

    • 我认为这可能与 timeit 尝试解析三引号注释有关。我定义了函数来使用 if-else 语句和三元运算符来评估该条件,使用 timeit.repeat 进行 100 次重复,并得到平均 0.81 秒(对于默认的 1,000,000 次运行)三元运算符,0.88 if-else 语句的秒数。
    【解决方案3】:

    我怀疑存在性能差异。它们编译成等效的字节码序列:

    >>> def f():
    ...   return a if b else c
    ...
    >>> dis.dis(f)
      2           0 LOAD_GLOBAL              0 (b)
                  2 POP_JUMP_IF_FALSE        8
                  4 LOAD_GLOBAL              1 (a)
                  6 RETURN_VALUE
            >>    8 LOAD_GLOBAL              2 (c)
                 10 RETURN_VALUE
    >>> def g():
    ...   if b:
    ...     return a
    ...   else:
    ...     return c
    ...
    >>> dis.dis(g)
      2           0 LOAD_GLOBAL              0 (b)
                  2 POP_JUMP_IF_FALSE        8
    
      3           4 LOAD_GLOBAL              1 (a)
                  6 RETURN_VALUE
    
      5     >>    8 LOAD_GLOBAL              2 (c)
                 10 RETURN_VALUE
                 12 LOAD_CONST               0 (None)
                 14 RETURN_VALUE
    

    与大多数性能问题一样,答案是衡量。

    【讨论】:

      猜你喜欢
      • 2018-08-07
      • 2021-07-09
      • 1970-01-01
      • 1970-01-01
      • 2011-05-10
      • 1970-01-01
      • 1970-01-01
      • 2015-06-05
      • 1970-01-01
      相关资源
      最近更新 更多