Skip to content

Commit

Permalink
specialize concatenation of lists and tuples
Browse files Browse the repository at this point in the history
  • Loading branch information
eendebakpt committed Jan 17, 2025
1 parent d95ba9f commit 336127e
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 2 deletions.
14 changes: 14 additions & 0 deletions Lib/test/test_opcache.py
Original file line number Diff line number Diff line change
Expand Up @@ -1362,6 +1362,20 @@ def binary_op_add_extend():
self.assert_specialized(binary_op_add_extend, "BINARY_OP_EXTEND")
self.assert_no_opcode(binary_op_add_extend, "BINARY_OP")

def binary_op_add_extend_sequences():
l1 = [1, 2]
l2 = [None]
t1 = (1, 2)
t2 = (None,)
for _ in range(100):
list_sum = l1 + l2
self.assertEqual(list_sum, [1, 2, None])
tuple_sum = t1 + t2
self.assertEqual(tuple_sum, (1, 2, None))

binary_op_add_extend_sequences()
self.assert_specialized(binary_op_add_extend_sequences, "BINARY_OP_EXTEND")
self.assert_no_opcode(binary_op_add_extend_sequences, "BINARY_OP")

@cpython_only
@requires_specialization_ft
Expand Down
2 changes: 1 addition & 1 deletion Objects/listobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ list_concat_lock_held(PyListObject *a, PyListObject *b)
return (PyObject *)np;
}

static PyObject *
PyObject *
list_concat(PyObject *aa, PyObject *bb)
{
if (!PyList_Check(bb)) {
Expand Down
2 changes: 1 addition & 1 deletion Objects/tupleobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ PyTuple_GetSlice(PyObject *op, Py_ssize_t i, Py_ssize_t j)
return tuple_slice((PyTupleObject *)op, i, j);
}

static PyObject *
PyObject *
tuple_concat(PyObject *aa, PyObject *bb)
{
PyTupleObject *a = _PyTuple_CAST(aa);
Expand Down
46 changes: 46 additions & 0 deletions Python/specialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -2414,6 +2414,50 @@ binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs)

/** Binary Op Specialization Extensions */

/* tuple-tuple*/

static int
tuple_tuple_guard(PyObject *lhs, PyObject *rhs)
{
return ( PyTuple_CheckExact(lhs) && PyTuple_CheckExact(rhs) );
}

extern PyObject * tuple_concat(PyObject *aa, PyObject *bb);

static PyObject * \
tuple_tuple_add(PyObject *lhs, PyObject *rhs) \
{
return tuple_concat(lhs, rhs);
}

static _PyBinaryOpSpecializationDescr tuple_tuple_specs[NB_OPARG_LAST+1] = {
[NB_ADD] = {tuple_tuple_guard, tuple_tuple_add},
};

/* list-list*/

static int
list_list_guard(PyObject *lhs, PyObject *rhs)
{
return ( PyList_CheckExact(lhs) && PyList_CheckExact(rhs) );
}

extern PyObject * list_concat(PyObject *aa, PyObject *bb);

static PyObject * \
list_list_add(PyObject *lhs, PyObject *rhs) \
{
return list_concat(lhs, rhs);
}

static _PyBinaryOpSpecializationDescr list_list_specs[NB_OPARG_LAST+1] = {
[NB_ADD] = {list_list_guard, list_list_add},
};

static binaryopactionfunc list_list_actions[NB_OPARG_LAST+1] = {
[NB_ADD] = list_list_add,
};

/* float-long */

static int
Expand Down Expand Up @@ -2494,6 +2538,8 @@ binary_op_extended_specialization(PyObject *lhs, PyObject *rhs, int oparg,

LOOKUP_SPEC(compactlong_float_specs, oparg);
LOOKUP_SPEC(float_compactlong_specs, oparg);
LOOKUP_SPEC(list_list_specs, oparg);
LOOKUP_SPEC(tuple_tuple_specs, oparg);
#undef LOOKUP_SPEC
return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions Tools/c-analyzer/cpython/ignored.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,8 @@ Python/specialize.c - adaptive_opcodes -
Python/specialize.c - cache_requirements -
Python/specialize.c - float_compactlong_specs -
Python/specialize.c - compactlong_float_specs -
Python/specialize.c - list_list_specs -
Python/specialize.c - tuple_tuple_specs -
Python/stdlib_module_names.h - _Py_stdlib_module_names -
Python/sysmodule.c - perf_map_state -
Python/sysmodule.c - _PySys_ImplCacheTag -
Expand Down

0 comments on commit 336127e

Please sign in to comment.