Skip to content

[mypyc] Use memmove to shift items in vec pop and remove - #22464

Open
Jahongir-Qurbonov wants to merge 1 commit into
python:masterfrom
Jahongir-Qurbonov:mypyc-vec-memmove
Open

Jahongir-Qurbonov wants to merge 1 commit into
python:masterfrom
Jahongir-Qurbonov:mypyc-vec-memmove

Conversation

@Jahongir-Qurbonov

Copy link
Copy Markdown
Contributor

vec pop and remove shift the remaining items with a loop like items[i] = items[i + 1]. GCC turns this loop into a memmove call (as a tail call), but clang 21 doesn't and emits a slower element-by-element loop. This PR calls memmove directly in vec_template.c, vec_t.c and vec_nested.c. The reference counting logic is unchanged.

Benchmark: pop(v, 0) repeated n/2 times on a copy of a vec with n items, librt built at -O3, CPython 3.13, Linux x86_64. Each number is the best of 15 runs, in ns per pop. pop(v) (no shift) takes ~75-90 ns in every build.

clang before clang after gcc before gcc after
vec[i64], n=16 89-94 94-96 96-99 95-96
vec[i64], n=1000 173-178 130-132 128-131 126-132
vec[i64], n=10000 1187-1255 786-795 781-792 782-790
vec[str], n=1000 167-177 142-144 135-142 135-139
vec[str], n=10000 972-1040 795-799 795-801 790-805

GCC builds don't change, and clang builds (such as macOS wheels) now match them.

Testing: the existing vec run tests cover pop with an index and remove for all vec kinds, including the shared buffer and decref ordering cases. They pass with both gcc and CC=clang.

GCC already compiles the item shifting loops into a memmove call, but
clang doesn't, so pop(0) on a large vec was ~35% slower in clang builds
(such as macOS wheels). Calling memmove directly makes clang builds as
fast as GCC builds.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant