Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improve performance of :c:func:`PySequence_GetSlice`.
15 changes: 7 additions & 8 deletions Objects/sliceobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ PyObject _Py_EllipsisObject = _PyObject_HEAD_INIT(&PyEllipsis_Type);
*/

static PySliceObject *
_PyBuildSlice_Consume2(PyObject *start, PyObject *stop, PyObject *step)
_PyBuildSlice_Consume3(PyObject *start, PyObject *stop, PyObject *step)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this consumes all its argument references, the 3 is unnecessary

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, this is now the same as _PyBuildSlice_ConsumeRefs, so you can rename this function and delete the other definition of _PyBuildSlice_ConsumeRefs

Copy link
Copy Markdown
Contributor Author

@eendebakpt eendebakpt Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _PyBuildSlice_ConsumeRefs only takes 2 arguments. I can delete it, but it would involve some churn (e.g. in bytecodes.c) because we have to add Py_None as a third argument.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@markshannon I merged the two methods!

{
assert(start != NULL && stop != NULL && step != NULL);
PySliceObject *obj = _Py_FREELIST_POP(PySliceObject, slices);
Expand All @@ -131,13 +131,14 @@ _PyBuildSlice_Consume2(PyObject *start, PyObject *stop, PyObject *step)

obj->start = start;
obj->stop = stop;
obj->step = Py_NewRef(step);
obj->step = step;

_PyObject_GC_TRACK(obj);
return obj;
error:
Py_DECREF(start);
Py_DECREF(stop);
Py_DECREF(step);
return NULL;
}

Expand All @@ -153,15 +154,15 @@ PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
if (stop == NULL) {
stop = Py_None;
}
return (PyObject *)_PyBuildSlice_Consume2(Py_NewRef(start),
Py_NewRef(stop), step);
return (PyObject *)_PyBuildSlice_Consume3(Py_NewRef(start),
Py_NewRef(stop), Py_NewRef(step));
}

PyObject *
_PyBuildSlice_ConsumeRefs(PyObject *start, PyObject *stop)
{
assert(start != NULL && stop != NULL);
return (PyObject *)_PyBuildSlice_Consume2(start, stop, Py_None);
return (PyObject *)_PyBuildSlice_Consume3(start, stop, Py_None);
}

PyObject *
Expand All @@ -177,9 +178,7 @@ _PySlice_FromIndices(Py_ssize_t istart, Py_ssize_t istop)
return NULL;
}

slice = PySlice_New(start, end, NULL);
Py_DECREF(start);
Py_DECREF(end);
slice = _PyBuildSlice_ConsumeRefs(start, end);
return slice;
}

Expand Down
Loading