From bcb6c0e1af0086b7900db518e73e61e48ee5167b Mon Sep 17 00:00:00 2001 From: scoder Date: Fri, 21 Apr 2023 08:25:20 +0200 Subject: Avoid Python int object creation when multiplying sequences with C integers (GH-5213) * Avoid redundant subtree analysis in MulNode when multiplying sequences with unknown types. * Avoid Python int creation when multiplying sequences with integers. * Also allow a cint mult_factor for sequences, avoiding Python coercion if possible. * Also optimise (int * ctuple), which will eventually end up as a Python tuple as well. * Make sure we only apply a "mult_factor" to a Python sequence (not ctuples), and make the re-analysis of TupleNode a little safer. --- Cython/Utility/ObjectHandling.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'Cython/Utility/ObjectHandling.c') diff --git a/Cython/Utility/ObjectHandling.c b/Cython/Utility/ObjectHandling.c index df9cc3457..e97569895 100644 --- a/Cython/Utility/ObjectHandling.c +++ b/Cython/Utility/ObjectHandling.c @@ -3086,6 +3086,36 @@ static CYTHON_INLINE PyObject *__Pyx_PyUnicode_ConcatInPlaceImpl(PyObject **p_le #define __Pyx_PyStr_ConcatInPlaceSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \ PyNumber_InPlaceAdd(a, b) : __Pyx_PyStr_ConcatInPlace(a, b)) + +/////////////// PySequenceMultiply.proto /////////////// + +#define __Pyx_PySequence_Multiply_Left(mul, seq) __Pyx_PySequence_Multiply(seq, mul) +static CYTHON_INLINE PyObject* __Pyx_PySequence_Multiply(PyObject *seq, Py_ssize_t mul); + +/////////////// PySequenceMultiply /////////////// + +static PyObject* __Pyx_PySequence_Multiply_Generic(PyObject *seq, Py_ssize_t mul) { + PyObject *result, *pymul = PyInt_FromSsize_t(mul); + if (unlikely(!pymul)) + return NULL; + result = PyNumber_Multiply(seq, pymul); + Py_DECREF(pymul); + return result; +} + +static CYTHON_INLINE PyObject* __Pyx_PySequence_Multiply(PyObject *seq, Py_ssize_t mul) { +#if CYTHON_USE_TYPE_SLOTS + PyTypeObject *type = Py_TYPE(seq); + if (likely(type->tp_as_sequence && type->tp_as_sequence->sq_repeat)) { + return type->tp_as_sequence->sq_repeat(seq, mul); + } else +#endif + { + return __Pyx_PySequence_Multiply_Generic(seq, mul); + } +} + + /////////////// FormatTypeName.proto /////////////// #if CYTHON_COMPILING_IN_LIMITED_API -- cgit v1.2.1