GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-100239: specialize left and right shift ops on ints by eendebakpt · Pull Request #129431 · python/cpython

Conversation

@eendebakpt

@eendebakpt eendebakpt commented Jan 29, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

We add a specialization for >> and >> on compact integers.

  • For both lshift and rshift we have to avoid undefined behavior for shifts larger than the number of bits in a C long.
  • The lshift operator << can overflow, so we restrict shifts to values smaller than 17. Under this assumption the value of a << b with b <= 16) fit into a 32-bit or 64-bit integer depending on the platform.

Benchmark:

bench_lshift_compactint: Mean +- std dev: [mainx2] 381 us +- 33 us -> [prx2] 334 us +- 46 us: 1.14x faster
bench_rshift_compactint: Mean +- std dev: [mainx2] 398 us +- 34 us -> [prx2] 281 us +- 46 us: 1.41x faster

Benchmark hidden because not significant (1): bench_rshift_largeint

Geometric mean: 1.17x **faster**

(non-PGO, Windows)

There is a gain with the specialization, but on the other hand: how many shift operations on compact ints are there? For example the shifts are used in the uuid module, but always on large ints.

  • Issue: Specialize long tail of binary operations using a table. #100239

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
eendebakpt added 2 commits January 29, 2025 11:12
@eendebakpt
specialize rshift on ints
f6d6e50
@eendebakpt
add test
dd53470
@bedevere-app bedevere-app Bot added the awaiting review label Jan 29, 2025
@bedevere-app bedevere-app Bot mentioned this pull request Jan 29, 2025
Specialize long tail of binary operations using a table. #100239
Open
eendebakpt added 3 commits January 29, 2025 12:15
@eendebakpt
handle case of negative shift
ca60ccc
@eendebakpt
handle case of negative shift
98015ac
@eendebakpt
handle case of negative shift
70ad42a
@eendebakpt eendebakpt added this to the hhhhhhhhhhhhhhhhhhhhhhhhhbbbbbbbb milestone Jan 29, 2025
@johnslavik

johnslavik commented Jan 29, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

@eendebakpt, something happened with the milestone.
image

eendebakpt reacted with confused emoji
All reactions
  • 😕 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@skirpichev skirpichev removed this from the hhhhhhhhhhhhhhhhhhhhhhhhhbbbbbbbb milestone Jan 29, 2025
@eendebakpt
Merge branch 'main' into binaryops_shift
e6af9b2
@eendebakpt
eendebakpt marked this pull request as draft January 29, 2025 19:51
@bedevere-app bedevere-app Bot removed the awaiting review label Jan 29, 2025
@eendebakpt
add lshift; avoid undefined behavior
004dce0
@eendebakpt eendebakpt changed the title gh-100239: specialize right shift ops on ints gh-100239: specialize left and right shift ops on ints Jan 29, 2025
eendebakpt and others added 4 commits January 29, 2025 22:40
@eendebakpt
tighten guard
32c68ae
@eendebakpt
use stwodigits for lshift
0085021
@blurb-it
📜🤖 Added by blurb_it.
3de0283
@eendebakpt
Merge branch 'main' into binaryops_shift
309f392
@eendebakpt
eendebakpt marked this pull request as ready for review January 30, 2025 20:16
@bedevere-app bedevere-app Bot added the awaiting review label Jan 30, 2025
eendebakpt added 2 commits January 31, 2025 11:09
@eendebakpt
add missing undef
1895d69
@eendebakpt
Merge branch 'main' into binaryops_shift
170cac8
@github-actions

github-actions Bot commented Apr 21, 2026

Copy link
Copy Markdown

This PR is stale because it has been open for 30 days with no activity.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label Apr 21, 2026
@eendebakpt
Merge branch 'main' into binaryops_shift
06900f5
# Conflicts:
#	Python/specialize.c
@eendebakpt

eendebakpt commented Apr 23, 2026

Copy link
Copy Markdown
Contributor Author

Updated benchmarks:

Benchmark main PR Δ
lshift_compactint (literal rhs 1–5) 12.9 ns 9.09 ns 1.42x faster
rshift_compactint (literal rhs 1–5) 19.3 ns 14.5 ns 1.33x faster
lshift_loop_var (rhs from range(16)) 400 ns 322 ns 1.25x faster
rshift_loop_var (rhs from range(16)) 384 ns 327 ns 1.17x faster
inplace_shift_mix (a <<= k; a >>= k) 15.0 ns 9.31 ns 1.61x faster
rshift_largeint (lhs = 1 << 200) 29.3 ns 29.3 ns not significant
Geometric mean — — 1.28x faster

rshift_largeint is the negative control — the guard correctly rejects non-compact operands, so large-int code pays zero overhead.

Benchmark script
"""Microbenchmarks for compact-int shift specialization (gh-100239)."""

import pyperf


def bench_lshift_compactint(loops):
    range_it = range(loops)
    a = 3
    t0 = pyperf.perf_counter()
    for _ in range_it:
        a << 1; a << 2; a << 3; a << 4; a << 5
        a << 1; a << 2; a << 3; a << 4; a << 5
        a << 1; a << 2; a << 3; a << 4; a << 5
        a << 1; a << 2; a << 3; a << 4; a << 5
    return pyperf.perf_counter() - t0


def bench_rshift_compactint(loops):
    range_it = range(loops)
    a = 1 << 20
    t0 = pyperf.perf_counter()
    for _ in range_it:
        a >> 1; a >> 2; a >> 3; a >> 4; a >> 5
        a >> 1; a >> 2; a >> 3; a >> 4; a >> 5
        a >> 1; a >> 2; a >> 3; a >> 4; a >> 5
        a >> 1; a >> 2; a >> 3; a >> 4; a >> 5
    return pyperf.perf_counter() - t0


def bench_rshift_largeint(loops):
    range_it = range(loops)
    a = 1 << 200
    t0 = pyperf.perf_counter()
    for _ in range_it:
        a >> 1; a >> 2; a >> 3; a >> 4; a >> 5
        a >> 1; a >> 2; a >> 3; a >> 4; a >> 5
        a >> 1; a >> 2; a >> 3; a >> 4; a >> 5
        a >> 1; a >> 2; a >> 3; a >> 4; a >> 5
    return pyperf.perf_counter() - t0


def bench_lshift_loop_var(loops):
    range_it = range(loops)
    t0 = pyperf.perf_counter()
    for _ in range_it:
        a = 5
        for i in range(16):
            a << i
    return pyperf.perf_counter() - t0


def bench_rshift_loop_var(loops):
    range_it = range(loops)
    t0 = pyperf.perf_counter()
    for _ in range_it:
        a = 1 << 16
        for i in range(16):
            a >> i
    return pyperf.perf_counter() - t0


def bench_inplace_lshift(loops):
    range_it = range(loops)
    t0 = pyperf.perf_counter()
    for _ in range_it:
        a = 1
        a <<= 1; a >>= 1
        a <<= 2; a >>= 2
        a <<= 3; a >>= 3
        a <<= 4; a >>= 4
        a <<= 5; a >>= 5
    return pyperf.perf_counter() - t0


if __name__ == "__main__":
    runner = pyperf.Runner()
    runner.bench_time_func("lshift_compactint", bench_lshift_compactint, inner_loops=20)
    runner.bench_time_func("rshift_compactint", bench_rshift_compactint, inner_loops=20)
    runner.bench_time_func("rshift_largeint",   bench_rshift_largeint,   inner_loops=20)
    runner.bench_time_func("lshift_loop_var",   bench_lshift_loop_var)
    runner.bench_time_func("rshift_loop_var",   bench_rshift_loop_var)
    runner.bench_time_func("inplace_shift_mix", bench_inplace_lshift,    inner_loops=10)
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

eendebakpt added 2 commits May 5, 2026 11:53
@eendebakpt
Merge branch 'main' into binaryops_shift
92bc898
@eendebakpt
fix c undefined behaviour
539d6bf
@read-the-docs-community

read-the-docs-community Bot commented May 5, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #35284648 | 📁 Comparing 539d6bf against main (f6d16a0)

  🔍 Preview build  

9 files changed · ± 9 modified

± Modified

  • c-api/type.html
  • library/datatypes.html
  • library/difflib.html
  • library/pprint.html
  • library/ssl.html
  • library/unittest.mock.html
  • tutorial/stdlib2.html
  • whatsnew/3.15.html
  • whatsnew/changelog.html
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot removed the stale Stale PR or inactive for long period of time. label May 14, 2026
@github-actions

github-actions Bot commented Aug 16, 2026

Copy link
Copy Markdown

This PR is stale because it has been open for 90 days with no activity.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label Aug 16, 2026
@ambv

ambv commented Oct 20, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

This PR is superseded by #156918, a newer open pull request for the same issue (gh-100239), and it no longer merges cleanly. Closing to cull the number of open pull requests. Do not reopen this pull request without getting a go-ahead from a triager or core developer.

Reopening. This was incorrectly closed as a duplicate.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ambv ambv closed this Oct 20, 2026
@ambv ambv reopened this Oct 21, 2026
@bedevere-app bedevere-app Bot added the type-feature A feature request or enhancement label Oct 21, 2026
@github-actions github-actions Bot removed the stale Stale PR or inactive for long period of time. label Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

awaiting review type-feature A feature request or enhancement

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

4 participants

@eendebakpt @johnslavik @ambv @skirpichev
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.