Skip to content

Commit 336127e

Browse files
committed
specialize concatenation of lists and tuples
1 parent d95ba9f commit 336127e

File tree

5 files changed

+64
-2
lines changed

5 files changed

+64
-2
lines changed

Lib/test/test_opcache.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,6 +1362,20 @@ def binary_op_add_extend():
13621362
self.assert_specialized(binary_op_add_extend, "BINARY_OP_EXTEND")
13631363
self.assert_no_opcode(binary_op_add_extend, "BINARY_OP")
13641364

1365+
def binary_op_add_extend_sequences():
1366+
l1 = [1, 2]
1367+
l2 = [None]
1368+
t1 = (1, 2)
1369+
t2 = (None,)
1370+
for _ in range(100):
1371+
list_sum = l1 + l2
1372+
self.assertEqual(list_sum, [1, 2, None])
1373+
tuple_sum = t1 + t2
1374+
self.assertEqual(tuple_sum, (1, 2, None))
1375+
1376+
binary_op_add_extend_sequences()
1377+
self.assert_specialized(binary_op_add_extend_sequences, "BINARY_OP_EXTEND")
1378+
self.assert_no_opcode(binary_op_add_extend_sequences, "BINARY_OP")
13651379

13661380
@cpython_only
13671381
@requires_specialization_ft

Objects/listobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ list_concat_lock_held(PyListObject *a, PyListObject *b)
734734
return (PyObject *)np;
735735
}
736736

737-
static PyObject *
737+
PyObject *
738738
list_concat(PyObject *aa, PyObject *bb)
739739
{
740740
if (!PyList_Check(bb)) {

Objects/tupleobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ PyTuple_GetSlice(PyObject *op, Py_ssize_t i, Py_ssize_t j)
459459
return tuple_slice((PyTupleObject *)op, i, j);
460460
}
461461

462-
static PyObject *
462+
PyObject *
463463
tuple_concat(PyObject *aa, PyObject *bb)
464464
{
465465
PyTupleObject *a = _PyTuple_CAST(aa);

Python/specialize.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2414,6 +2414,50 @@ binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs)
24142414

24152415
/** Binary Op Specialization Extensions */
24162416

2417+
/* tuple-tuple*/
2418+
2419+
static int
2420+
tuple_tuple_guard(PyObject *lhs, PyObject *rhs)
2421+
{
2422+
return ( PyTuple_CheckExact(lhs) && PyTuple_CheckExact(rhs) );
2423+
}
2424+
2425+
extern PyObject * tuple_concat(PyObject *aa, PyObject *bb);
2426+
2427+
static PyObject * \
2428+
tuple_tuple_add(PyObject *lhs, PyObject *rhs) \
2429+
{
2430+
return tuple_concat(lhs, rhs);
2431+
}
2432+
2433+
static _PyBinaryOpSpecializationDescr tuple_tuple_specs[NB_OPARG_LAST+1] = {
2434+
[NB_ADD] = {tuple_tuple_guard, tuple_tuple_add},
2435+
};
2436+
2437+
/* list-list*/
2438+
2439+
static int
2440+
list_list_guard(PyObject *lhs, PyObject *rhs)
2441+
{
2442+
return ( PyList_CheckExact(lhs) && PyList_CheckExact(rhs) );
2443+
}
2444+
2445+
extern PyObject * list_concat(PyObject *aa, PyObject *bb);
2446+
2447+
static PyObject * \
2448+
list_list_add(PyObject *lhs, PyObject *rhs) \
2449+
{
2450+
return list_concat(lhs, rhs);
2451+
}
2452+
2453+
static _PyBinaryOpSpecializationDescr list_list_specs[NB_OPARG_LAST+1] = {
2454+
[NB_ADD] = {list_list_guard, list_list_add},
2455+
};
2456+
2457+
static binaryopactionfunc list_list_actions[NB_OPARG_LAST+1] = {
2458+
[NB_ADD] = list_list_add,
2459+
};
2460+
24172461
/* float-long */
24182462

24192463
static int
@@ -2494,6 +2538,8 @@ binary_op_extended_specialization(PyObject *lhs, PyObject *rhs, int oparg,
24942538

24952539
LOOKUP_SPEC(compactlong_float_specs, oparg);
24962540
LOOKUP_SPEC(float_compactlong_specs, oparg);
2541+
LOOKUP_SPEC(list_list_specs, oparg);
2542+
LOOKUP_SPEC(tuple_tuple_specs, oparg);
24972543
#undef LOOKUP_SPEC
24982544
return 0;
24992545
}

Tools/c-analyzer/cpython/ignored.tsv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,8 @@ Python/specialize.c - adaptive_opcodes -
380380
Python/specialize.c - cache_requirements -
381381
Python/specialize.c - float_compactlong_specs -
382382
Python/specialize.c - compactlong_float_specs -
383+
Python/specialize.c - list_list_specs -
384+
Python/specialize.c - tuple_tuple_specs -
383385
Python/stdlib_module_names.h - _Py_stdlib_module_names -
384386
Python/sysmodule.c - perf_map_state -
385387
Python/sysmodule.c - _PySys_ImplCacheTag -

0 commit comments

Comments
 (0)