From bd1cf6ecee76bcdce87b4f69567b95756ecf5a4c Mon Sep 17 00:00:00 2001 From: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> Date: Wed, 23 Mar 2022 14:00:05 +0530 Subject: bpo-47012: speed up iteration of bytes and bytearray (GH-31867) --- Include/internal/pycore_long.h | 10 ++++++++-- .../Core and Builtins/2022-03-14-11-15-11.bpo-47012.5L6NoE.rst | 1 + Objects/bytearrayobject.c | 9 +++------ Objects/bytesobject.c | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-03-14-11-15-11.bpo-47012.5L6NoE.rst diff --git a/Include/internal/pycore_long.h b/Include/internal/pycore_long.h index 436bf08..a337624 100644 --- a/Include/internal/pycore_long.h +++ b/Include/internal/pycore_long.h @@ -23,8 +23,9 @@ extern void _PyLong_FiniTypes(PyInterpreterState *interp); #define _PyLong_SMALL_INTS _Py_SINGLETON(small_ints) // _PyLong_GetZero() and _PyLong_GetOne() must always be available -#if _PY_NSMALLPOSINTS < 2 -# error "_PY_NSMALLPOSINTS must be greater than 1" +// _PyLong_FromUnsignedChar must always be available +#if _PY_NSMALLPOSINTS < 257 +# error "_PY_NSMALLPOSINTS must be greater than or equal to 257" #endif // Return a borrowed reference to the zero singleton. @@ -37,6 +38,11 @@ static inline PyObject* _PyLong_GetZero(void) static inline PyObject* _PyLong_GetOne(void) { return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; } +static inline PyObject* _PyLong_FromUnsignedChar(unsigned char i) +{ + return Py_NewRef((PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i]); +} + PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right); PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right); PyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right); diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-14-11-15-11.bpo-47012.5L6NoE.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-14-11-15-11.bpo-47012.5L6NoE.rst new file mode 100644 index 0000000..f85487f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-14-11-15-11.bpo-47012.5L6NoE.rst @@ -0,0 +1 @@ +Speed up iteration of :class:`bytes` and :class:`bytearray` by 30%. Patch by Kumar Aditya. diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index ba2d347..cbe673a 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -6,6 +6,7 @@ #include "pycore_bytes_methods.h" #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_strhex.h" // _Py_strhex_with_sep() +#include "pycore_long.h" // _PyLong_FromUnsignedChar() #include "bytesobject.h" /*[clinic input] @@ -2428,7 +2429,6 @@ static PyObject * bytearrayiter_next(bytesiterobject *it) { PyByteArrayObject *seq; - PyObject *item; assert(it != NULL); seq = it->it_seq; @@ -2437,11 +2437,8 @@ bytearrayiter_next(bytesiterobject *it) assert(PyByteArray_Check(seq)); if (it->it_index < PyByteArray_GET_SIZE(seq)) { - item = PyLong_FromLong( - (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]); - if (item != NULL) - ++it->it_index; - return item; + return _PyLong_FromUnsignedChar( + (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index++]); } it->it_seq = NULL; diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index fd1c58c..0039532 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3133,7 +3133,7 @@ striter_next(striterobject *it) assert(PyBytes_Check(seq)); if (it->it_index < PyBytes_GET_SIZE(seq)) { - return PyLong_FromLong( + return _PyLong_FromUnsignedChar( (unsigned char)seq->ob_sval[it->it_index++]); } -- cgit v0.12