In Python, are expressions like 10**9
made of literals also literals? What I am asking: is there a cost to using expressions over less-meaningful but also less-computable literals in code that is called very often and should be lightweight?

- 4,520
- 4
- 39
- 61
4 Answers
There is no performance cost. Consider this:
import dis
def foo():
x = 10**9
y = 10**9
def bar():
x = 1000000000
y = 1000000000
dis.dis(foo)
dis.dis(bar)
yields
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
So when Python compiles the code, it changes the 10**9
to 1000000000
. By the time the byte-code is run, there is no difference between using 10**9
or 1000000000
.

- 842,883
- 184
- 1,785
- 1,677
-
I think this "constant folding" is cpython implementation detail, though. – wim Dec 13 '15 at 01:26
It's more about readability and coding style. By writing something like 10**9
instead of 1000000000
or etc., you'll make your code shorter and more readable, thus its maintenance and improvement would be easier. If you want to use 10**9
multiple times in your code, as a more elegant way you'd better use it as a global variable at the top level of your module which is more elegant. Like:
MY_VARIABLE = 10**9
Note that even if you don't use a global variable name and use its numerical value through your code python will assume it's a constant value and won't recalculate it every time.
For example, as you can see in the following bytecode, python will load the constant value (which you defined in first part for a
) for c
and doesn't create a new object 1 for that:
>>> 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
Note that python small integers are singletons and python will create only one copy of them (-5 to 256).

- 105,000
- 18
- 159
- 188
-
4It's not more readable because it's shorter. It's more readable because you don't have to count zeroes. – Dec 12 '15 at 11:34
-
1
-
After self reflection, I made some time measurements:
>>> import timeit
>>> def f():
... return 10**9
>>> timeit.timeit(f)
0.13885498046875
>>> def f():
... return 1000000000
>>> timeit.timeit(f)
0.13900208473205566

- 4,520
- 4
- 39
- 61
There is a cost to using expressions, namely a performance cost due to Python precomputing constant expressions, but this cost is not likely to be noticeable in most cases, like in the case of 10**9
, more so with cases like 10**(10**10)
.
-
Good reference! So what you are saying is that computation is added, but one-time compile-time? – ArekBulski Dec 13 '15 at 12:07