mirror of https://github.com/python/cpython
Adopt Skip's idea to optimize lists of constants in the context
of a "in" or "not in" test.
This commit is contained in:
parent
fe59dc1bd8
commit
7fcb7869ba
|
@ -135,7 +135,8 @@ class TestTranforms(unittest.TestCase):
|
||||||
|
|
||||||
def test_set_conversion(self):
|
def test_set_conversion(self):
|
||||||
for line in (
|
for line in (
|
||||||
'x in (1,2,3)',
|
'x in [1,2,3]',
|
||||||
|
'x in (1,2,3)',
|
||||||
'x not in (1,2,3)',
|
'x not in (1,2,3)',
|
||||||
'not x in (1,2,3)',
|
'not x in (1,2,3)',
|
||||||
'not x not in (1,2,3)',
|
'not x not in (1,2,3)',
|
||||||
|
|
|
@ -397,7 +397,9 @@ intern_strings(PyObject *tuple)
|
||||||
The consts table must still be in list form so that the
|
The consts table must still be in list form so that the
|
||||||
new constant (c1, c2, ... cn) can be appended.
|
new constant (c1, c2, ... cn) can be appended.
|
||||||
Called with codestr pointing to the first LOAD_CONST.
|
Called with codestr pointing to the first LOAD_CONST.
|
||||||
Bails out with no change if one or more of the LOAD_CONSTs is missing. */
|
Bails out with no change if one or more of the LOAD_CONSTs is missing.
|
||||||
|
Also works for BUILD_LIST when followed by an "in" or "not in" test.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
tuple_of_constants(unsigned char *codestr, int n, PyObject *consts)
|
tuple_of_constants(unsigned char *codestr, int n, PyObject *consts)
|
||||||
{
|
{
|
||||||
|
@ -406,7 +408,7 @@ tuple_of_constants(unsigned char *codestr, int n, PyObject *consts)
|
||||||
|
|
||||||
/* Pre-conditions */
|
/* Pre-conditions */
|
||||||
assert(PyList_CheckExact(consts));
|
assert(PyList_CheckExact(consts));
|
||||||
assert(codestr[n*3] == BUILD_TUPLE);
|
assert(codestr[n*3] == BUILD_TUPLE || codestr[n*3] == BUILD_LIST);
|
||||||
assert(GETARG(codestr, (n*3)) == n);
|
assert(GETARG(codestr, (n*3)) == n);
|
||||||
for (i=0 ; i<n ; i++)
|
for (i=0 ; i<n ; i++)
|
||||||
assert(codestr[i*3] == LOAD_CONST);
|
assert(codestr[i*3] == LOAD_CONST);
|
||||||
|
@ -753,24 +755,28 @@ optimize_code(PyObject *code, PyObject* consts, PyObject *names, PyObject *linen
|
||||||
cumlc = 0;
|
cumlc = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Try to fold tuples of constants.
|
/* Try to fold tuples of constants (includes a case for lists
|
||||||
|
which are only used for "in" and "not in" tests).
|
||||||
Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
|
Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
|
||||||
Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
|
Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
|
||||||
Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
|
Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
|
||||||
case BUILD_TUPLE:
|
case BUILD_TUPLE:
|
||||||
|
case BUILD_LIST:
|
||||||
j = GETARG(codestr, i);
|
j = GETARG(codestr, i);
|
||||||
h = i - 3 * j;
|
h = i - 3 * j;
|
||||||
if (h >= 0 &&
|
if (h >= 0 &&
|
||||||
j <= lastlc &&
|
j <= lastlc &&
|
||||||
ISBASICBLOCK(blocks, h, 3*(j+1)) &&
|
(opcode == BUILD_TUPLE &&
|
||||||
|
ISBASICBLOCK(blocks, h, 3*(j+1)) ||
|
||||||
|
opcode == BUILD_LIST &&
|
||||||
|
codestr[i+3]==COMPARE_OP &&
|
||||||
|
ISBASICBLOCK(blocks, h, 3*(j+2)) &&
|
||||||
|
(GETARG(codestr,i+3)==6 || GETARG(codestr,i+3)==7)) &&
|
||||||
tuple_of_constants(&codestr[h], j, consts)) {
|
tuple_of_constants(&codestr[h], j, consts)) {
|
||||||
assert(codestr[i] == LOAD_CONST);
|
assert(codestr[i] == LOAD_CONST);
|
||||||
cumlc = 1;
|
cumlc = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Intentional fallthrough */
|
|
||||||
case BUILD_LIST:
|
|
||||||
j = GETARG(codestr, i);
|
|
||||||
if (codestr[i+3] != UNPACK_SEQUENCE ||
|
if (codestr[i+3] != UNPACK_SEQUENCE ||
|
||||||
!ISBASICBLOCK(blocks,i,6) ||
|
!ISBASICBLOCK(blocks,i,6) ||
|
||||||
j != GETARG(codestr, i+3))
|
j != GETARG(codestr, i+3))
|
||||||
|
|
Loading…
Reference in New Issue