Friday Finking: initialising values and implied tuples
Rob Cliffe
rob.cliffe at btinternet.com
Mon Apr 5 13:18:50 EDT 2021
On 05/04/2021 17:52, Chris Angelico wrote:
> On Tue, Apr 6, 2021 at 2:32 AM Rob Cliffe via Python-list
> <python-list at python.org> wrote:
>>
>>
>> It doesn't appear to, at least not always. In Python 3.8.3:
>> from dis import dis
>> def f(): x = 1 ; y = 2
>> def g(): (x,y) = (1,2)
>> dis(f)
>> dis(g)
>>
>> Output:
>> 2 0 LOAD_CONST 1 (1)
>> 2 STORE_FAST 0 (x)
>> 4 LOAD_CONST 2 (2)
>> 6 STORE_FAST 1 (y)
>> 8 LOAD_CONST 0 (None)
>> 10 RETURN_VALUE
>> 3 0 LOAD_CONST 1 ((1, 2))
>> 2 UNPACK_SEQUENCE 2
>> 4 STORE_FAST 0 (x)
>> 6 STORE_FAST 1 (y)
>> 8 LOAD_CONST 0 (None)
>> 10 RETURN_VALUE
>> Thinking some more about this, this (removing the tuples) is not a
>> straightforward optimisation to do.
> It's important to be aware of the semantics here. Saying "x = 1; y =
> 2" requires that x be set before 2 is calculated (imagine if it had
> been "y = x + 2" or something), whereas "x, y = 1, 2" has to do the
> opposite, fully evaluating the right hand side before doing any of the
> assignments.
>
>> I guess it's safe if the RHS is a tuple containing only
>> constants, by which I think I mean number/string literals and
>> built-in constants (None, True etc.).
>> variables (NOT expressions containing variables such as "z+1")
>> which do not occur on the LHS
>> tuple/list/dictionary/set displays which themselves contain only
>> the above, or nested displays which themselves ... etc.
> Nope, there's no "it's safe if" other than constants - which are
> already handled differently.
How are constants handled differently (apart from using LOAD_CONST)?
See my dis example above.
> If there is ANY Python code executed to
> calculate those values, it could depend on the previous assignments
> being completed.
I don't understand. What semantic difference could there be between
x = { 1: 2 } ; y = [3, 4] ; z = (5, 6)
and
x, y, z = { 1:2 }, [3, 4], (5, 6)
? Why is it not safe to convert the latter to the former?
But I withdraw "set" from my "safe" list because I now realise that
"set" could be reassigned.
>
> But the tuples aren't a problem here. They're a highly optimized way
> of grabbing multiple things at once. In the "x, y = 1, 2" case, the
> compiler would be free to implement it as "LOAD_CONST 1, LOAD_CONST 2,
> ROT_TWO, STORE_FAST x, STORE_FAST y" (equivalent to what you'd see for
> "x, y = y, x"), but it doesn't, so we can fairly confidently expect
> that the tuple is faster.
Not according to the Windows timings I mentioned in my previous post.
>
> BTW, if you want to play around with CPython's optimizations, there's
> another case to consider:
>
> def f(): x = y = 1
> 1 0 LOAD_CONST 1 (1)
> 2 DUP_TOP
> 4 STORE_FAST 0 (x)
> 6 STORE_FAST 1 (y)
>
> The constant gets loaded once (which is semantically important), and
> then duplicated on the stack, leaving two available for storing. Feel
> free to play around with different combinations here. For instance,
> "x, y = a, b = 1, 2" should now be unsurprising, but perhaps there'll
> be some more complicated examples that are interesting to explore.
>
> I love dis stuff. :)
>
> ChrisA
Best wishes
Rob Cliffe
More information about the Python-list
mailing list