Strange disassembly
Terry Reedy
tjreedy at udel.edu
Sat Jun 19 05:23:29 EDT 2021
On 6/18/2021 8:13 PM, Chris Angelico wrote:
> On Sat, Jun 19, 2021 at 9:50 AM Terry Reedy <tjreedy at udel.edu> wrote:
>>> Why are there two separate bytecode blocks for the "raise Exception"?
>>
>> Because one block must POP_TOP and other must not.
>>
>>> I'd have thought that the double condition would still be evaluated as
>>> one thing, or at least that the jump destinations for both the
>>> early-abort and the main evaluation should be the same.
>>
>> To reuse the exception block with POP_TOP, could jump over it after the
>> 2nd compare.
>
> Hmm, fair enough I guess. The compiler figured that it'd be faster to
> duplicate the executable code rather than have the jump.
I would not assume that any alternative was considered.
> It made for a
> somewhat confusing disassembly, but I presume it's faster to run.
>
>> For the simplest and fasted bytecode, write normal logic and let x be
>> reloaded instead of duplicated and rotated.
>>
>> >>> import dis
>> >>> def f(x):
>> ... if x <= 0 or 10 <= x: raise Exception
>> ...
>> ...
>> >>> dis.dis(f)
>> 2 0 LOAD_FAST 0 (x)
>> 2 LOAD_CONST 1 (0)
>> 4 COMPARE_OP 1 (<=)
>> 6 POP_JUMP_IF_TRUE 8 (to 16)
>> 8 LOAD_CONST 2 (10)
>> 10 LOAD_FAST 0 (x)
>> 12 COMPARE_OP 1 (<=)
>> 14 POP_JUMP_IF_FALSE 10 (to 20)
>> >> 16 LOAD_GLOBAL 0 (Exception)
>> 18 RAISE_VARARGS 1
>> >> 20 LOAD_CONST 0 (None)
>> 22 RETURN_VALUE
>> >>>
>>
>
> Makes sense. I'm not sure if this would actually run faster, but I
> can't really justify warping my code around the disassembly :)
>
> Thanks for the explanation. I guess I just assumed the interpreter
> would prefer a jump to the duplication, but that's a decision it's
> free to take!
--
Terry Jan Reedy
More information about the Python-list
mailing list