使用 10**9 的成本超过 1000000000?
Cost of using 10**9 over 1000000000?
在Python中,像10**9
这样由文字构成的表达式也是文字吗?我要问的是:在经常调用且应该是轻量级的代码中使用表达式而不是意义不大但计算性较差的文字是否有成本?
没有性能成本。考虑一下:
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**9
或 1000000000
之间没有区别。
更多的是关于可读性和编码风格。通过写类似 10**9
而不是 1000000000
之类的东西,你会让你的代码更短,更易读,因此它的维护和改进会更容易。如果你想在代码中多次使用 10**9
,作为一种更优雅的方式,你最好将它用作模块顶层的全局变量,这样更优雅。喜欢:
MY_VARIABLE = 10**9
注意 即使您不使用全局变量名称并通过您的代码使用它的数值 python 也会假定它是一个常数值并且不会'每次都重新计算。
例如,正如您在以下字节码中所见,python 将为 c
加载常量值(您在第一部分为 a
定义的值)并且不会t 为此创建一个新对象 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 小整数是 单数 并且 python 将只创建它们的一个副本(-5 到 256)。
经过自我反省,我做了一些时间测量:
>>> import timeit
>>> def f():
... return 10**9
>>> timeit.timeit(f)
0.13885498046875
>>> def f():
... return 1000000000
>>> timeit.timeit(f)
0.13900208473205566
是使用表达式的成本,即由于Python precomputing constant expressions导致的性能成本,但这种成本在大多数情况下不太可能引起注意,例如10**9
的情况更是如此 10**(10**10)
.
在Python中,像10**9
这样由文字构成的表达式也是文字吗?我要问的是:在经常调用且应该是轻量级的代码中使用表达式而不是意义不大但计算性较差的文字是否有成本?
没有性能成本。考虑一下:
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**9
或 1000000000
之间没有区别。
更多的是关于可读性和编码风格。通过写类似 10**9
而不是 1000000000
之类的东西,你会让你的代码更短,更易读,因此它的维护和改进会更容易。如果你想在代码中多次使用 10**9
,作为一种更优雅的方式,你最好将它用作模块顶层的全局变量,这样更优雅。喜欢:
MY_VARIABLE = 10**9
注意 即使您不使用全局变量名称并通过您的代码使用它的数值 python 也会假定它是一个常数值并且不会'每次都重新计算。
例如,正如您在以下字节码中所见,python 将为 c
加载常量值(您在第一部分为 a
定义的值)并且不会t 为此创建一个新对象 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 小整数是 单数 并且 python 将只创建它们的一个副本(-5 到 256)。
经过自我反省,我做了一些时间测量:
>>> import timeit
>>> def f():
... return 10**9
>>> timeit.timeit(f)
0.13885498046875
>>> def f():
... return 1000000000
>>> timeit.timeit(f)
0.13900208473205566
是使用表达式的成本,即由于Python precomputing constant expressions导致的性能成本,但这种成本在大多数情况下不太可能引起注意,例如10**9
的情况更是如此 10**(10**10)
.