On Sat, Jun 19, 2021 at 4:16 PM Rob Cliffe via Python-list <python-list@python.org> wrote: > > > > On 18/06/2021 11:04, Chris Angelico wrote: > >>>> sys.version > > '3.10.0b2+ (heads/3.10:33a7a24288, Jun 9 2021, 20:47:39) [GCC 8.3.0]' > >>>> def chk(x): > > ... if not(0 < x < 10): raise Exception > > ... > >>>> dis.dis(chk) > > 2 0 LOAD_CONST 1 (0) > > 2 LOAD_FAST 0 (x) > > 4 DUP_TOP > > 6 ROT_THREE > > 8 COMPARE_OP 0 (<) > > 10 POP_JUMP_IF_FALSE 11 (to 22) > > 12 LOAD_CONST 2 (10) > > 14 COMPARE_OP 0 (<) > > 16 POP_JUMP_IF_TRUE 14 (to 28) > > 18 LOAD_GLOBAL 0 (Exception) > > 20 RAISE_VARARGS 1 > > >> 22 POP_TOP > > 24 LOAD_GLOBAL 0 (Exception) > > 26 RAISE_VARARGS 1 > > >> 28 LOAD_CONST 0 (None) > > 30 RETURN_VALUE > > Why are there two separate bytecode blocks for the "raise Exception"? > > 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. > > > > ChrisA > As an ornery human I could refactor this to avoid the code duplication as > > 2 0 LOAD_CONST 1 (0) > 2 LOAD_FAST 0 (x) > 4 DUP_TOP > 6 ROT_THREE > 8 COMPARE_OP 0 (<) > 10 POP_JUMP_IF_TRUE 10 (to 18) > 12 POP_TOP > >> 14 LOAD_GLOBAL 0 (Exception) > 16 RAISE_VARARGS 1 > >> 18 LOAD_CONST 2 (10) > 20 COMPARE_OP 0 (<) > 22 POP_JUMP_IF_FALSE 21 (to 14) > 24 LOAD_CONST 0 (None) > 26 RETURN_VALUE > >>> > > (there may be mistakes in this) but this is probably too much to expect > of the compiler.
Hmm, I think that depends too much on knowing that the raise won't return. That might be a neat optimization (effectively a form of dead code removal), but otherwise, the best you could do would be to also have it jump out after the raise. ChrisA -- https://mail.python.org/mailman/listinfo/python-list