[Tutor] For - if - else loop; print selective output

eryksun eryksun at gmail.com
Wed Oct 24 22:10:13 CEST 2012


On Wed, Oct 24, 2012 at 3:24 PM, Alan Gauld <alan.gauld at btinternet.com> wrote:
> On 24/10/12 18:49, eryksun wrote:
>
>> Using "in ['25', '26']" also checks a compiled tuple constant:
>>
>>      >>> compile("x in ['25', '26']", '', 'eval').co_consts
>>      ('25', '26', ('25', '26'))
>>
>> 3.x adds frozenset support:
>>
>>      >>> compile("x in {'25', '26'}", '', 'eval').co_consts
>>      ('25', '26', frozenset({'25', '26'}))
>
>
> I confess I don't know what that means!
> And if I don't I doubt if the OP will either.
> Can you explain the above in English please?

Sorry, I was showing that the compiler (at least for CPython) special
cases "in" and "not in" comparisons when the right-hand operand is a
list literal of constants. Instead of going to the trouble of building
a list every time the code runs, it uses a tuple that's stored in the
code object's co_consts attribute.

In Python 3, this optimization was extended to set literals constants.
I guess I should show that in more detail by disassembling a function
instead of manually compiling code.

First in Python 2.7.3:

    >>> def func(x):
    ...     return x in {1, 2, 3}

    >>> dis.dis(func)
      2           0 LOAD_FAST                0 (x)
                  3 LOAD_CONST               1 (1)
                  6 LOAD_CONST               2 (2)
                  9 LOAD_CONST               3 (3)
                 12 BUILD_SET                3
                 15 COMPARE_OP               6 (in)
                 18 RETURN_VALUE

Each time the function is called it has to build a set (BUILD_SET)
from the constants 1, 2, and 3. Compare that to Python 3.2.3:

    >>> dis.dis(func)
      2           0 LOAD_FAST                0 (x)
                  3 LOAD_CONST               4 (frozenset({1, 2, 3}))
                  6 COMPARE_OP               6 (in)
                  9 RETURN_VALUE

Here the compiler stored a frozenset in the code object. So it only
has to load the frozenset on the stack instead of building a new set
each time the function is called.

compile:
http://docs.python.org/py3k/library/functions.html#compile

frozenset:
http://docs.python.org/py3k/library/functions.html#func-frozenset

code objects:
http://docs.python.org/py3k/reference/datamodel.html#index-51

The optimization is in peephole.c, PyCode_Optimize/tuple_of_constants:

http://hg.python.org/cpython/file/3d0686d90f55/Python/peephole.c#l469
http://hg.python.org/cpython/file/3d0686d90f55/Python/peephole.c#l25


More information about the Tutor mailing list