-
-
Notifications
You must be signed in to change notification settings - Fork 33.8k
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?
gh-128213: fast path for bytes creation from list and tuple #132590
Conversation
…sing PyNumber_AsSsize_t; fixed indentation
Misc/NEWS.d/next/Core_and_Builtins/2024-12-24-08-44-49.gh-issue-128213.Y71jDi.rst
Outdated
Show resolved
Hide resolved
Misc/NEWS.d/next/Core_and_Builtins/2024-12-24-08-44-49.gh-issue-128213.Y71jDi.rst
Outdated
Show resolved
Hide resolved
Objects/bytesobject.c
Outdated
| /* 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 comment
The reason will be displayed to describe this comment to others. Learn more.
| /* Py_None as a fallback sentinel to the slow path */ | |
| bytes = Py_None; | |
| /* Py_None as a fallback sentinel to the slow path */ | |
| Py_INCREF(Py_None); | |
| bytes = Py_None; |
Is needed, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Py_None is immortal, so not needed
| goto error; | ||
| PyObject *const *items = PySequence_Fast_ITEMS(x); | ||
| for (Py_ssize_t i = 0; i < size; i++) { | ||
| if (!PyLong_Check(items[i])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're interested in speed, PyLong_CheckExact will allow you to use _PyLong_IsNonNegativeCompact and _PyLong_CompactValue to get the C int in a few cycles.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. For the common/happy path we now we call PyNumber_AsSsize_t, which calls PyLong_AsSsize_t. That methods does another PyLong_Check and then a call to _PyLong_IsCompact.
So we have some options:
- We could remove the call to
PyLong_Check(as it is already covered byPyLong_AsSsize_t), that improves performance a bit for all cases. - We could use
PyLong_CheckExactwith_PyLong_IsNonNegativeCompact. Fastest for exact ints, but non-exact ints become slower. I suspect non-exact ints are rare though. - We add a fast path using
PyLong_CheckExactand a fallback fast path usingPyNumber_AsSsize_tfor the non-exacts ints. Fast for all cases, but takes a but more code.
@markshannon Any preference? I am happy to work out any of the above.
|
Tuples are immutable, so why does creating a bytes object from a tuple require synchronization? |
Tuples indeed do not require synchronization. In this PR exact lists and tuples use the path (using synchronization with |
Continuation of #128214. This PR