Skip to content
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

gh-128118: Improve performance of copy.copy by using a fast lookup for atomic and container types #128119

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

eendebakpt
Copy link
Contributor

@eendebakpt eendebakpt commented Dec 20, 2024

Similar to the approached used for copy.deepcopy in #114266 we can simplifly the implementation of copy.copy and improve performance by checking on the type of the argument using a lookup.

Results:

copy int: Mean +- std dev: [main] 159 ns +- 10 ns -> [pr_v2] 104 ns +- 7 ns: 1.54x faster
copy slice: Mean +- std dev: [main] 184 ns +- 44 ns -> [pr_v2] 109 ns +- 13 ns: 1.69x faster
copy dict: Mean +- std dev: [main] 196 ns +- 18 ns -> [pr_v2] 182 ns +- 16 ns: 1.07x faster
copy dataclass: Mean +- std dev: [main] 1.88 us +- 0.13 us -> [pr_v2] 1.82 us +- 0.11 us: 1.04x faster
copy small list: Mean +- std dev: [main] 179 ns +- 18 ns -> [pr_v2] 134 ns +- 7 ns: 1.33x faster
copy small tuple: Mean +- std dev: [main] 155 ns +- 12 ns -> [pr_v2] 80.3 ns +- 6.1 ns: 1.93x faster
copy list dataclasses: Mean +- std dev: [main] 151 ns +- 11 ns -> [pr_v2] 160 ns +- 25 ns: 1.05x slower

Geometric mean: 1.32x faster

Benchmark script:

import pyperf

runner = pyperf.Runner()

setup = """
import copy

a={'list': [1,2,3,43], 't': (1,2,3), 'str': 'hello', 'subdict': {'a': True}}

from dataclasses import dataclass

lst = [1, 's']
tpl  =('a', 'b', 3)

i = 123123123
sl = slice(1,2,3)

@dataclass
class A:
    a : int
    
dc = A(123)
list_dc = [A(1), A(2), A(3), A(4)]
"""

runner.timeit(name="copy int", stmt="b=copy.copy(i)", setup=setup)
runner.timeit(name="copy slice", stmt="b=copy.copy(sl)", setup=setup)
runner.timeit(name="copy dict", stmt="b=copy.copy(a)", setup=setup)
runner.timeit(name="copy dataclass", stmt="b=copy.copy(dc)", setup=setup)
runner.timeit(name="copy small list", stmt="b=copy.copy(lst)", setup=setup)
runner.timeit(name="copy small tuple", stmt="b=copy.copy(tpl)", setup=setup)
runner.timeit(name="copy list dataclasses", stmt="b=copy.copy(list_dc)", setup=setup)

@eendebakpt eendebakpt changed the title Improve performance of copy.copy by using a fast lookup for atomic and container types gh-128118: Improve performance of copy.copy by using a fast lookup for atomic and container types Dec 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants