]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-47012: speed up iteration of bytes and bytearray (GH-31867)
authorKumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Wed, 23 Mar 2022 08:30:05 +0000 (14:00 +0530)
committerGitHub <noreply@github.com>
Wed, 23 Mar 2022 08:30:05 +0000 (04:30 -0400)
Include/internal/pycore_long.h
Misc/NEWS.d/next/Core and Builtins/2022-03-14-11-15-11.bpo-47012.5L6NoE.rst [new file with mode: 0644]
Objects/bytearrayobject.c
Objects/bytesobject.c

index 436bf0846859976f073ad9b3dbcb287837a37f72..a33762402491b74c3e4117199de3bb295c20d151 100644 (file)
@@ -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 (file)
index 0000000..f85487f
--- /dev/null
@@ -0,0 +1 @@
+Speed up iteration of :class:`bytes` and :class:`bytearray` by 30%. Patch by Kumar Aditya.
index ba2d347dbd7a87c2ad3879820ce19c7c869c4221..cbe673acd0a3a98d8c7d43761c4f2990a816353d 100644 (file)
@@ -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;
index fd1c58c2f233ebae7ffad44a2568331e1fcda09f..003953244a885a5e00e0bc38e0ed40a36eb3fd83 100644 (file)
@@ -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++]);
     }