Optimising literals away
Thomas Jollans
thomas at jollybox.de
Mon Aug 30 11:53:24 EDT 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