Jason Baker
Jason Baker

Reputation: 198517

What optimizations does Python do without the -O flags?

I had always assumed that the Python interpreter did no optimizations without a -O flag, but the following is a bit strange:

>>> def foo():
...     print '%s' % 'Hello world'
...
>>> from dis import dis 
>>> dis(foo)
  2           0 LOAD_CONST               3 ('Hello world')
              3 PRINT_ITEM          
              4 PRINT_NEWLINE       
              5 LOAD_CONST               0 (None)
              8 RETURN_VALUE        

It appears as though the interpreter is doing some folding on the modulo of two string constants. If I add a variable in though, it gives an unoptimized result:

>>> def foo():
...     s = 'Hello world!'
...     print '%s' % s
... 
>>> dis(foo)
  2           0 LOAD_CONST               1 ('Hello world!')
              3 STORE_FAST               0 (s)

  3           6 LOAD_CONST               2 ('%s')
              9 LOAD_FAST                0 (s)
             12 BINARY_MODULO       
             13 PRINT_ITEM          
             14 PRINT_NEWLINE       
             15 LOAD_CONST               0 (None)
             18 RETURN_VALUE        

What optimizations does Python do without the -O flag? And is there any way to disable them? I'd like to see how unoptimized Python bytecode will look. I don't plan on doing this in any production type environment.

Upvotes: 4

Views: 339

Answers (2)

d33tah
d33tah

Reputation: 11561

Here's a way to walk around constant folding:

>>> dis.dis(lambda: (3,)[0]+(4,)[0])
  1           0 LOAD_CONST               5 (3)
              3 LOAD_CONST               7 (4)
              6 BINARY_ADD          
              7 RETURN_VALUE        

Watch out for the extra constants, though:

>>> (lambda: (3,)[0]+(4,0)[0]).func_code.co_consts
(None, 3, 0, 4, (3,), 3, (4, 0), 4)

Upvotes: 0

Alex Martelli
Alex Martelli

Reputation: 881477

Yep, it does do constant folding, here's a simpler example:

>>> def f(): return 23+100
... 
>>> dis.dis(f)
  1           0 LOAD_CONST               3 (123)
              3 RETURN_VALUE        
>>> 

No way to block this (except by changing sources) AFAIK.

Edit: for all the optimization flow, see peephole.c -- this is also probably the handiest place to "change sources", e.g. change line 320 from

if (codelen > 32700)

to

if (codelen > 0)

to make sure all optimizations are unconditionally disabled.

Upvotes: 9

Related Questions