【问题标题】:Cost of using 10**9 over 1000000000?使用 10**9 超过 1000000000 的成本?
【发布时间】:2015-12-12 11:10:56
【问题描述】:

在 Python 中,像 10**9 这样由文字组成的表达式也是文字吗?我要问的是:在经常调用且应该是轻量级的代码中使用表达式而不是意义较小但可计算性较低的文字是否有成本?

【问题讨论】:

    标签: python performance python-2.7 literals


    【解决方案1】:

    没有性能成本。考虑一下:

    import dis
    def foo():
        x = 10**9
        y = 10**9
    
    def bar():
        x = 1000000000
        y = 1000000000
    
    dis.dis(foo)
    dis.dis(bar)
    

    产量

    In [6]: dis.dis(foo)
      5           0 LOAD_CONST               3 (1000000000)
                  3 STORE_FAST               0 (x)
    
      6           6 LOAD_CONST               4 (1000000000)
                  9 STORE_FAST               1 (y)
                 12 LOAD_CONST               0 (None)
                 15 RETURN_VALUE        
    
    In [8]: dis.dis(bar)
      9           0 LOAD_CONST               1 (1000000000)
                  3 STORE_FAST               0 (x)
    
     10           6 LOAD_CONST               1 (1000000000)
                  9 STORE_FAST               1 (y)
                 12 LOAD_CONST               0 (None)
                 15 RETURN_VALUE        
    

    所以当 Python 编译代码时,它会将 10**9 更改为 1000000000。到运行字节码时,使用10**91000000000 没有区别。

    【讨论】:

    • 我认为这个“常量折叠”是 cpython 的实现细节。
    【解决方案2】:

    更多的是关于可读性和编码风格。通过编写类似10**9 而不是1000000000 之类的东西,您将使您的代码更短且更具可读性,因此它的维护和改进会更容易。如果您想在代码中多次使用10**9,作为一种更优雅的方式,您最好将其用作模块顶层的全局变量,这样更优雅。喜欢:

    MY_VARIABLE = 10**9
    

    注意,即使您不使用全局变量名并在代码中使用其数值,python 也会假定它是一个常量值,并且不会每次都重新计算它。

    例如,正如您在以下字节码中看到的,python 将为c 加载常量值(您在第一部分中为a 定义)并且不会创建新对象1 为此:

    >>> def test():
    ...    a = 10**9
    ...    b = 1000000000
    ...    c = 10**9
    ... 
    >>> dis.dis(test)
      2           0 LOAD_CONST               4 (1000000000)
                  3 STORE_FAST               0 (a)
    
      3           6 LOAD_CONST               3 (1000000000)
                  9 STORE_FAST               1 (b)
    
      4          12 LOAD_CONST               5 (1000000000)
                 15 STORE_FAST               2 (c)
                 18 LOAD_CONST               0 (None)
                 21 RETURN_VALUE    
    

    请注意,python 小整数是 singletons,python 只会创建它们的一个副本(-5 到 256)。

    【讨论】:

    • 它不是更易读,因为它更短。它更具可读性,因为您不必数零。
    • @Rhymoid 确实,这就是我的意思。
    • nit:你的 b 是 10**8
    【解决方案3】:

    自我反省后,我做了一些时间测量:

    >>> import timeit
    
    >>> def f():
    ...     return 10**9
    
    >>> timeit.timeit(f)
    0.13885498046875
    
    >>> def f():
    ...     return 1000000000
    
    >>> timeit.timeit(f)
    0.13900208473205566
    

    【讨论】:

      【解决方案4】:

      使用表达式的成本,即由于Python precomputing constant expressions 导致的性能成本,但这种成本在大多数情况下不太可能引起注意,例如10**9,像10**(10**10) 这样的案例更是如此。

      【讨论】:

      • 好参考!所以你的意思是添加了计算,但是一次性编译时间?
      猜你喜欢
      • 2017-03-12
      • 1970-01-01
      • 1970-01-01
      • 2018-06-11
      • 1970-01-01
      • 2012-07-21
      • 1970-01-01
      • 2020-11-24
      • 2019-10-04
      相关资源
      最近更新 更多