mirror of
https://github.com/python/cpython.git
synced 2026-01-26 12:55:08 +00:00
gh-132108: Add Buffer Protocol support to int.from_bytes to improve performance (#132109)
Speed up conversion from `bytes-like` objects like `bytearray` while keeping conversion from `bytes` stable. Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com> Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
parent
e5b5a15804
commit
510ab7d6e1
@ -0,0 +1,2 @@
|
||||
Speed up :meth:`int.from_bytes` when passed object supports :ref:`buffer
|
||||
protocol <bufferobjects>`, like :class:`bytearray` by ~1.2x.
|
||||
@ -6476,14 +6476,33 @@ int_from_bytes_impl(PyTypeObject *type, PyObject *bytes_obj,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bytes = PyObject_Bytes(bytes_obj);
|
||||
if (bytes == NULL)
|
||||
return NULL;
|
||||
|
||||
long_obj = _PyLong_FromByteArray(
|
||||
(unsigned char *)PyBytes_AS_STRING(bytes), Py_SIZE(bytes),
|
||||
little_endian, is_signed);
|
||||
Py_DECREF(bytes);
|
||||
/* Fast-path exact bytes. */
|
||||
if (PyBytes_CheckExact(bytes_obj)) {
|
||||
long_obj = _PyLong_FromByteArray(
|
||||
(unsigned char *)PyBytes_AS_STRING(bytes_obj), Py_SIZE(bytes_obj),
|
||||
little_endian, is_signed);
|
||||
}
|
||||
/* Use buffer protocol to avoid copies. */
|
||||
else if (PyObject_CheckBuffer(bytes_obj)) {
|
||||
Py_buffer view;
|
||||
if (PyObject_GetBuffer(bytes_obj, &view, PyBUF_SIMPLE) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
long_obj = _PyLong_FromByteArray(view.buf, view.len, little_endian,
|
||||
is_signed);
|
||||
PyBuffer_Release(&view);
|
||||
}
|
||||
else {
|
||||
/* fallback: Construct a bytes then convert. */
|
||||
bytes = PyObject_Bytes(bytes_obj);
|
||||
if (bytes == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
long_obj = _PyLong_FromByteArray(
|
||||
(unsigned char *)PyBytes_AS_STRING(bytes), Py_SIZE(bytes),
|
||||
little_endian, is_signed);
|
||||
Py_DECREF(bytes);
|
||||
}
|
||||
|
||||
if (long_obj != NULL && type != &PyLong_Type) {
|
||||
Py_SETREF(long_obj, PyObject_CallOneArg((PyObject *)type, long_obj));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user