Uh oh!
There was an error while loading. Please reload this page.
gh-128213: fast path for bytes creation from list and tuple - #132590
gh-128213: fast path for bytes creation from list and tuple#132590eendebakpt wants to merge 33 commits into
Conversation
…sing PyNumber_AsSsize_t; fixed indentation
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| 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.
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.
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.
There was a problem hiding this comment.
The PyNumber_AsSsize_t performs an incref/decref on the argument which we can avoid by calling PyLong_AsSsize_t directly (the incref is not very bad, since in the happy path the argument will be in the 0 to 255 range so a python small int, but still). I updated the PR with this approach.
Most important for the PR is making the code thread-safe, so I left the possible optimization with _PyLong_IsNonNegativeCompact out for now.
markshannon
commented
Jan 6, 2026
Tuples are immutable, so why does creating a bytes object from a tuple require synchronization? |
eendebakpt
commented
Jan 6, 2026
Tuples indeed do not require synchronization. In this PR exact lists and tuples use the path (using synchronization with |
Uh oh!
There was an error while loading. Please reload this page.
eendebakpt
commented
Apr 20, 2026
@markshannon Would you be able to continue reviewing this one? |
eendebakpt
commented
Jun 8, 2026
@colesbury Would you be able to review? |
Continuation of #128214. This PR
_PyList_GetItemRef).