Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cost of using 10**9 over 1000000000?

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?

like image 373
ArekBulski Avatar asked Dec 12 '15 11:12

ArekBulski


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

like image 99
unutbu Avatar answered Oct 06 '22 23:10

unutbu


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

like image 39
Mazdak Avatar answered Oct 06 '22 23:10

Mazdak