Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7fcb786

Browse files
committed
Adopt Skip's idea to optimize lists of constants in the context
of a "in" or "not in" test.
1 parent fe59dc1 commit 7fcb786

2 files changed

Lines changed: 15 additions & 8 deletions

File tree

Lib/test/test_peepholer.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ def test_folding_of_binops_on_constants(self):
135135

136136
def test_set_conversion(self):
137137
for line in (
138-
'x in (1,2,3)',
138+
'x in [1,2,3]',
139+
'x in (1,2,3)',
139140
'x not in (1,2,3)',
140141
'not x in (1,2,3)',
141142
'not x not in (1,2,3)',

Python/compile.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,9 @@ intern_strings(PyObject *tuple)
397397
The consts table must still be in list form so that the
398398
new constant (c1, c2, ... cn) can be appended.
399399
Called with codestr pointing to the first LOAD_CONST.
400-
Bails out with no change if one or more of the LOAD_CONSTs is missing. */
400+
Bails out with no change if one or more of the LOAD_CONSTs is missing.
401+
Also works for BUILD_LIST when followed by an "in" or "not in" test.
402+
*/
401403
static int
402404
tuple_of_constants(unsigned char *codestr, int n, PyObject *consts)
403405
{
@@ -406,7 +408,7 @@ tuple_of_constants(unsigned char *codestr, int n, PyObject *consts)
406408

407409
/* Pre-conditions */
408410
assert(PyList_CheckExact(consts));
409-
assert(codestr[n*3] == BUILD_TUPLE);
411+
assert(codestr[n*3] == BUILD_TUPLE || codestr[n*3] == BUILD_LIST);
410412
assert(GETARG(codestr, (n*3)) == n);
411413
for (i=0 ; i<n ; i++)
412414
assert(codestr[i*3] == LOAD_CONST);
@@ -753,24 +755,28 @@ optimize_code(PyObject *code, PyObject* consts, PyObject *names, PyObject *linen
753755
cumlc = 0;
754756
break;
755757

756-
/* Try to fold tuples of constants.
758+
/* Try to fold tuples of constants (includes a case for lists
759+
which are only used for "in" and "not in" tests).
757760
Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
758761
Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
759762
Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
760763
case BUILD_TUPLE:
764+
case BUILD_LIST:
761765
j = GETARG(codestr, i);
762766
h = i - 3 * j;
763767
if (h >= 0 &&
764768
j <= lastlc &&
765-
ISBASICBLOCK(blocks, h, 3*(j+1)) &&
769+
(opcode == BUILD_TUPLE &&
770+
ISBASICBLOCK(blocks, h, 3*(j+1)) ||
771+
opcode == BUILD_LIST &&
772+
codestr[i+3]==COMPARE_OP &&
773+
ISBASICBLOCK(blocks, h, 3*(j+2)) &&
774+
(GETARG(codestr,i+3)==6 || GETARG(codestr,i+3)==7)) &&
766775
tuple_of_constants(&codestr[h], j, consts)) {
767776
assert(codestr[i] == LOAD_CONST);
768777
cumlc = 1;
769778
break;
770779
}
771-
/* Intentional fallthrough */
772-
case BUILD_LIST:
773-
j = GETARG(codestr, i);
774780
if (codestr[i+3] != UNPACK_SEQUENCE ||
775781
!ISBASICBLOCK(blocks,i,6) ||
776782
j != GETARG(codestr, i+3))

0 commit comments

Comments
 (0)