Optimising literals away

Thomas Jollans thomas at jollybox.de
Mon Aug 30 17:53:24 CEST 2010


On Monday 30 August 2010, it occurred to Tobias Weber to exclaim:
> Hi,
> whenever I type an "object literal" I'm unsure what optimisation will do
> to it.
> 
> def m(arg):
>   if arg & set([1,2,3]):
>     return 4
> 
> Is the set created every time the method is called? What about a
> frozenset? Or tuple vs list? After how many calls per second does it pay
> to save it at the module level? Would anybody else find this ugly?

That creates a list, and then calls "set" with the list as an argument. Every 
time, because that's what the code says: call "set" with a new list containing 
1, 2, and 3.

If you use a tuple instead of the list, the tuple can be loaded as a whole -- 
as tuples are immutable, it doesn't have to be re-created every time, it can 
be the same object.

If you use a set literal instead of calling "set", the set is constructed 
directly, like a list would be.

Details:

>>> def m_l(arg):
...     if arg & set([1,2,3]):
...         return 4
... 
>>> def m_t(arg):
...     if arg & set((1,2,3)):
...         return 4
... 
>>> def m_s(arg):
...     if arg & {1, 2, 3}:
...         return 4
... 
>>> from dis import dis
>>> dis(m_l)
  2           0 LOAD_FAST                0 (arg) 
              3 LOAD_GLOBAL              0 (set) 
              6 LOAD_CONST               1 (1) 
              9 LOAD_CONST               2 (2) 
             12 LOAD_CONST               3 (3) 
             15 BUILD_LIST               3 
             18 CALL_FUNCTION            1 
             21 BINARY_AND           
             22 POP_JUMP_IF_FALSE       29 

  3          25 LOAD_CONST               4 (4) 
             28 RETURN_VALUE         
        >>   29 LOAD_CONST               0 (None) 
             32 RETURN_VALUE         
>>> dis(m_t)
  2           0 LOAD_FAST                0 (arg) 
              3 LOAD_GLOBAL              0 (set) 
              6 LOAD_CONST               5 ((1, 2, 3)) 
              9 CALL_FUNCTION            1 
             12 BINARY_AND           
             13 POP_JUMP_IF_FALSE       20 

  3          16 LOAD_CONST               4 (4) 
             19 RETURN_VALUE         
        >>   20 LOAD_CONST               0 (None) 
             23 RETURN_VALUE         
>>> dis(m_s)
  2           0 LOAD_FAST                0 (arg) 
              3 LOAD_CONST               1 (1) 
              6 LOAD_CONST               2 (2) 
              9 LOAD_CONST               3 (3) 
             12 BUILD_SET                3 
             15 BINARY_AND           
             16 POP_JUMP_IF_FALSE       23 

  3          19 LOAD_CONST               4 (4) 
             22 RETURN_VALUE         
        >>   23 LOAD_CONST               0 (None) 
             26 RETURN_VALUE         
>>> 



More information about the Python-list mailing list