https://github.com/python/cpython/commit/510ab7d6e1284dd2ac453b780fa19b5627bca0e1 commit: 510ab7d6e1284dd2ac453b780fa19b5627bca0e1 branch: main author: Cody Maloney <[email protected]> committer: vstinner <[email protected]> date: 2026-01-13T10:33:26+01:00 summary:
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 <[email protected]> Co-authored-by: Victor Stinner <[email protected]> files: A Misc/NEWS.d/next/Core_and_Builtins/2025-04-04-20-38-29.gh-issue-132108.UwZIQy.rst M Objects/longobject.c diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-04-04-20-38-29.gh-issue-132108.UwZIQy.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-04-20-38-29.gh-issue-132108.UwZIQy.rst new file mode 100644 index 00000000000000..8c2d947954c5bb --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-04-20-38-29.gh-issue-132108.UwZIQy.rst @@ -0,0 +1,2 @@ +Speed up :meth:`int.from_bytes` when passed object supports :ref:`buffer +protocol <bufferobjects>`, like :class:`bytearray` by ~1.2x. diff --git a/Objects/longobject.c b/Objects/longobject.c index 8ba1fd65078f48..74958cb8b9bbb0 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -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)); _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]
