# 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)
15 BUILD_LIST               3
18 CALL_FUNCTION            1
21 BINARY_AND
22 POP_JUMP_IF_FALSE       29

28 RETURN_VALUE
32 RETURN_VALUE
>>> dis(m_t)
6 LOAD_CONST               5 ((1, 2, 3))
9 CALL_FUNCTION            1
12 BINARY_AND
13 POP_JUMP_IF_FALSE       20

19 RETURN_VALUE
23 RETURN_VALUE
>>> dis(m_s)
12 BUILD_SET                3
15 BINARY_AND
16 POP_JUMP_IF_FALSE       23