Skip to content

Commit bd1cf6e

Browse files
bpo-47012: speed up iteration of bytes and bytearray (GH-31867)
1 parent 894d0ea commit bd1cf6e

File tree

4 files changed

+13
-9
lines changed

4 files changed

+13
-9
lines changed

Include/internal/pycore_long.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ extern void _PyLong_FiniTypes(PyInterpreterState *interp);
2323
#define _PyLong_SMALL_INTS _Py_SINGLETON(small_ints)
2424

2525
// _PyLong_GetZero() and _PyLong_GetOne() must always be available
26-
#if _PY_NSMALLPOSINTS < 2
27-
# error "_PY_NSMALLPOSINTS must be greater than 1"
26+
// _PyLong_FromUnsignedChar must always be available
27+
#if _PY_NSMALLPOSINTS < 257
28+
# error "_PY_NSMALLPOSINTS must be greater than or equal to 257"
2829
#endif
2930

3031
// Return a borrowed reference to the zero singleton.
@@ -37,6 +38,11 @@ static inline PyObject* _PyLong_GetZero(void)
3738
static inline PyObject* _PyLong_GetOne(void)
3839
{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; }
3940

41+
static inline PyObject* _PyLong_FromUnsignedChar(unsigned char i)
42+
{
43+
return Py_NewRef((PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i]);
44+
}
45+
4046
PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right);
4147
PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right);
4248
PyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Speed up iteration of :class:`bytes` and :class:`bytearray` by 30%. Patch by Kumar Aditya.

Objects/bytearrayobject.c

+3-6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "pycore_bytes_methods.h"
77
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
88
#include "pycore_strhex.h" // _Py_strhex_with_sep()
9+
#include "pycore_long.h" // _PyLong_FromUnsignedChar()
910
#include "bytesobject.h"
1011

1112
/*[clinic input]
@@ -2428,7 +2429,6 @@ static PyObject *
24282429
bytearrayiter_next(bytesiterobject *it)
24292430
{
24302431
PyByteArrayObject *seq;
2431-
PyObject *item;
24322432

24332433
assert(it != NULL);
24342434
seq = it->it_seq;
@@ -2437,11 +2437,8 @@ bytearrayiter_next(bytesiterobject *it)
24372437
assert(PyByteArray_Check(seq));
24382438

24392439
if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2440-
item = PyLong_FromLong(
2441-
(unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
2442-
if (item != NULL)
2443-
++it->it_index;
2444-
return item;
2440+
return _PyLong_FromUnsignedChar(
2441+
(unsigned char)PyByteArray_AS_STRING(seq)[it->it_index++]);
24452442
}
24462443

24472444
it->it_seq = NULL;

Objects/bytesobject.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -3133,7 +3133,7 @@ striter_next(striterobject *it)
31333133
assert(PyBytes_Check(seq));
31343134

31353135
if (it->it_index < PyBytes_GET_SIZE(seq)) {
3136-
return PyLong_FromLong(
3136+
return _PyLong_FromUnsignedChar(
31373137
(unsigned char)seq->ob_sval[it->it_index++]);
31383138
}
31393139

0 commit comments

Comments
 (0)