On 3/10/2011 11:23 AM, Gerald Britton wrote:
Today I noticed that an expression like this:

"one:%(one)s two:%(two)s" % {"one": "is the loneliest number", "two":
"can be as bad as one"}

could be evaluated at compile time, but is not:

In fact, it could be evaluated at writing time ;-).
This would be an example of constant folding, except that a dict is not, in itself, a constant.

dis(compile(
... '"one:%(one)s two:%(two)s" % {"one": "is the loneliest number",
"two": "can be as bad as one"}',
... '','exec'))
  1           0 LOAD_CONST               0 ('one:%(one)s two:%(two)s')
              3 BUILD_MAP                2
              6 LOAD_CONST               1 ('is the loneliest number')
              9 LOAD_CONST               2 ('one')
             12 STORE_MAP
             13 LOAD_CONST               3 ('can be as bad as one')
             16 LOAD_CONST               4 ('two')
             19 STORE_MAP
             20 BINARY_MODULO
             21 POP_TOP
             22 LOAD_CONST               5 (None)
             25 RETURN_VALUE


Any idea why Python works this way?

Because that is how the language is defined.

 I see that, in 3.2, an
optimization was done for sets (See "Optimizations" at
http://docs.python.org/py3k/whatsnew/3.2.html) though I do not see
anything similar for dictionaries.

I presume you mean this:

"Python’s peephole optimizer now recognizes patterns such x in {1, 2, 3} as being a test for membership in a set of constants. The optimizer recasts the set as a frozenset and stores the pre-built constant.

Now that the speed penalty is gone, it is practical to start writing membership tests using set-notation. This style is both semantically clear and operationally fast:

extension = name.rpartition('.')[2]
if extension in {'xml', 'html', 'xhtml', 'css'}:
    handle(name)

(Patch and additional tests contributed by Dave Malcolm; issue 6690)."

This is possible because: sets have a frozen counterpart, and cpython *sometimes* follows an 'as if' rule for optimizations. There is no frozendict, so the same pattern could not be followed.

Note first that the optimization is *not* an example of constant folding, but recognition that an unbound mutable cannot be mutated, and therefore, if all its contents are fixed, can be 'cast' to constant form at compile time.

Note second that the optimization does not apply to all such set instances, but only to this particular 'in' context. It follows a similar optimization for turning lists into tuples (although in this latter case, the programmer could have remembered to use () instead of []).

The optimization *did* happen because various people started an issue, wrote a patch, reviewed the patch, and committed it to the cpython source. You might read the issue if you have not:

http://bugs.python.org/issue6690

Terry Jan Reedy


--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to