9

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?

ArekBulski
  • 4,520
  • 4
  • 39
  • 61

4 Answers4

13

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.

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
7

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).

Mazdak
  • 105,000
  • 18
  • 159
  • 188
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
ArekBulski
  • 4,520
  • 4
  • 39
  • 61
1

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).

Community
  • 1
  • 1
Peter O.
  • 32,158
  • 14
  • 82
  • 96