-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
gh-128213: fast path for bytes creation from list and tuple #132590
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
6f699b5
18c8e4a
406fbdb
4912a05
56f802e
4e1e3e6
bf96d06
f3a9423
8bbc021
8260c7a
bc6f8f2
970c10b
cb664fe
c357217
5d53346
739987e
8b7c5e6
ab82e24
2e5c3c1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
…ark notes
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
Speed up :class:`bytes` creation from :class:`list` and :class:`tuple` by around 81%. | ||
Speed up :class:`bytes` creation from :class:`list` and :class:`tuple` of integers. Benchmarks show that from a list with 1000000 random numbers the time to create a bytes object is reduced by around 31%, or 30% with 10000 numbers, or 27% with 100 numbers. | ||
|
||
eendebakpt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Patch by Ben Hsing |
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -6,6 +6,7 @@ | |||||||||||
#include "pycore_bytesobject.h" // _PyBytes_Find(), _PyBytes_Repeat() | ||||||||||||
#include "pycore_call.h" // _PyObject_CallNoArgs() | ||||||||||||
#include "pycore_ceval.h" // _PyEval_GetBuiltin() | ||||||||||||
#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST() | ||||||||||||
#include "pycore_format.h" // F_LJUST | ||||||||||||
#include "pycore_global_objects.h"// _Py_GET_GLOBAL_OBJECT() | ||||||||||||
#include "pycore_initconfig.h" // _PyStatus_OK() | ||||||||||||
|
@@ -2813,18 +2814,21 @@ | |||||||||||
_PyBytes_FromSequence(PyObject *x) | ||||||||||||
{ | ||||||||||||
Py_ssize_t size = PySequence_Fast_GET_SIZE(x); | ||||||||||||
PyObject *bytes = PyBytes_FromStringAndSize(NULL, size); | ||||||||||||
if (bytes == NULL) | ||||||||||||
PyObject *bytes = _PyBytes_FromSize(size, 0); | ||||||||||||
if (bytes == NULL) { | ||||||||||||
return NULL; | ||||||||||||
char *s = PyBytes_AS_STRING(bytes); | ||||||||||||
PyObject **items = PySequence_Fast_ITEMS(x); | ||||||||||||
} | ||||||||||||
char *str = PyBytes_AS_STRING(bytes); | ||||||||||||
PyObject *const *items = PySequence_Fast_ITEMS(x); | ||||||||||||
Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST(x); | ||||||||||||
for (Py_ssize_t i = 0; i < size; i++) { | ||||||||||||
if (!PyLong_CheckExact(items[i])) { | ||||||||||||
if (!PyLong_Check(items[i])) { | ||||||||||||
Py_DECREF(bytes); | ||||||||||||
return Py_None; // None as fallback sentinel to the slow path | ||||||||||||
/* Py_None as a fallback sentinel to the slow path */ | ||||||||||||
bytes = Py_None; | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Is needed, no? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Py_None is immortal, so not needed |
||||||||||||
goto done; | ||||||||||||
} | ||||||||||||
int overflow; | ||||||||||||
long value = PyLong_AsLongAndOverflow(items[i], &overflow); | ||||||||||||
int value = PyLong_AsInt(items[i]); | ||||||||||||
if (value == -1 && PyErr_Occurred()) { | ||||||||||||
goto error; | ||||||||||||
} | ||||||||||||
|
@@ -2834,12 +2838,16 @@ | |||||||||||
"bytes must be in range(0, 256)"); | ||||||||||||
goto error; | ||||||||||||
} | ||||||||||||
s[i] = (char)value; | ||||||||||||
*str++ = (char) value; | ||||||||||||
} | ||||||||||||
return bytes; | ||||||||||||
goto done; | ||||||||||||
error: | ||||||||||||
Py_DECREF(bytes); | ||||||||||||
return NULL; | ||||||||||||
bytes = NULL; | ||||||||||||
done: | ||||||||||||
/* both success and failure need to end the critical section */ | ||||||||||||
Py_END_CRITICAL_SECTION_SEQUENCE_FAST(); | ||||||||||||
Check failure on line 2849 in Objects/bytesobject.c
|
||||||||||||
return bytes; | ||||||||||||
} | ||||||||||||
|
||||||||||||
static PyObject * | ||||||||||||
|
@@ -2924,6 +2932,7 @@ | |||||||||||
|
||||||||||||
if (PyList_CheckExact(x) || PyTuple_CheckExact(x)) { | ||||||||||||
PyObject *bytes = _PyBytes_FromSequence(x); | ||||||||||||
/* Py_None as a fallback sentinel to the slow path */ | ||||||||||||
if (bytes != Py_None) { | ||||||||||||
return bytes; | ||||||||||||
} | ||||||||||||
|
Uh oh!
There was an error while loading. Please reload this page.