Skip to content

Make copy.deepcopy faster for slice objects #100817

Description

@sobolevn

slice

Right now slice objects are deepcopied using __reduce__ defined as:

static PyObject *
slice_reduce(PySliceObject* self, PyObject *Py_UNUSED(ignored))
{
return Py_BuildValue("O(OOO)", Py_TYPE(self), self->start, self->stop, self->step);
}

It is one of last branches of deepcopy logic:

cpython/Lib/copy.py

Lines 120 to 157 in 26ff436

def deepcopy(x, memo=None, _nil=[]):
"""Deep copy operation on arbitrary Python objects.
See the module's __doc__ string for more info.
"""
if memo is None:
memo = {}
d = id(x)
y = memo.get(d, _nil)
if y is not _nil:
return y
cls = type(x)
copier = _deepcopy_dispatch.get(cls)
if copier is not None:
y = copier(x, memo)
else:
if issubclass(cls, type):
y = _deepcopy_atomic(x, memo)
else:
copier = getattr(x, "__deepcopy__", None)
if copier is not None:
y = copier(memo)
else:
reductor = dispatch_table.get(cls)
if reductor:
rv = reductor(x)
else:
reductor = getattr(x, "__reduce_ex__", None)
if reductor is not None:
rv = reductor(4)
else:
reductor = getattr(x, "__reduce__", None)
if reductor:
rv = reductor()

But, since slice is an immutable type without nested structures, we can optimize its deepcopy as:

d[slice] = _deepcopy_atomic

Before:

» pyperf timeit --setup 'from copy import deepcopy; s = slice(1,10,2)' 'deepcopy(s)'
.....................
Mean +- std dev: 3.46 us +- 0.18 us

After:

» pyperf timeit --setup 'from copy import deepcopy; s = slice(1,10,2)' 'deepcopy(s)'
.....................
Mean +- std dev: 277 ns +- 3 ns

Looks like a good speedup for just a single line!
Noticed while working on #100815

PR is incoming.

Linked PRs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

performancePerformance or resource usagetype-featureA feature request or enhancement

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions