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-74690: Micro-optimise `typing._get_protocol_attrs` by AlexWaygood · Pull Request #103152 · python/cpython

Conversation

@AlexWaygood

@AlexWaygood AlexWaygood commented Mar 31, 2023 •
edited by bedevere-bot
Loading

Uh oh!

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

Copy link
Copy Markdown
Member

This PR is a bunch of micro-optimisations for typing._get_protocol_attrs that together have a significant impact on the speed of isinstance checks against runtime-checkable protocols.

Benchmark:
import time
from typing import Protocol, runtime_checkable

@runtime_checkable
class HasX(Protocol):
    x: int

class Foo:
    @property
    def x(self) -> int:
        return 42

class Bar:
    x = 42

class Baz:
    def __init__(self):
        self.x = 42

class Egg: ...

class Nominal(HasX):
    def __init__(self):
        self.x = 42

class Registered: ...

HasX.register(Registered)

num_instances = 500_000
foos = [Foo() for _ in range(num_instances)]
bars = [Bar() for _ in range(num_instances)]
bazzes = [Baz() for _ in range(num_instances)]
basket = [Egg() for _ in range(num_instances)]
nominals = [Nominal() for _ in range(num_instances)]
registereds = [Registered() for _ in range(num_instances)]


def bench(objs, title):
    start_time = time.perf_counter()
    for obj in objs:
        isinstance(obj, HasX)
    elapsed = time.perf_counter() - start_time
    print(f"{title}: {elapsed:.2f}")


bench(foos, "Time taken for objects with a property")
bench(bars, "Time taken for objects with a classvar")
bench(bazzes, "Time taken for objects with an instance var")
bench(basket, "Time taken for objects with no var")
bench(nominals, "Time taken for nominal subclass instances")
bench(registereds, "Time taken for registered subclass instances")

Results on dfc4c95:

Time taken for objects with a property: 2.17
Time taken for objects with a classvar: 2.10
Time taken for objects with an instance var: 2.13
Time taken for objects with no var: 2.47
Time taken for nominal subclass instances: 2.20
Time taken for registered subclass instances: 4.72

Results with this PR:

Time taken for objects with a property: 1.65
Time taken for objects with a classvar: 1.60
Time taken for objects with an instance var: 1.61
Time taken for objects with no var: 1.89
Time taken for nominal subclass instances: 1.61
Time taken for registered subclass instances: 3.79

I'm once again skipping NEWS, since #103034 will counteract the boost to performance here, so the overall impact on performance for runtime-checkable protocols in 3.12 is still TBD.

  • Issue: Performance of typing._ProtocolMeta._get_protocol_attrs and isinstance #74690

Sorry, something went wrong.

Uh oh!

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

All reactions
@AlexWaygood
pythongh-74690: Micro-optimise typing._get_protocol_attrs
b4ddcc9
@AlexWaygood AlexWaygood added type-feature A feature request or enhancement performance Performance or resource usage skip news stdlib Standard Library Python modules in the Lib/ directory topic-typing 3.12 only security fixes labels Mar 31, 2023
@AlexWaygood
AlexWaygood requested a review from carljm March 31, 2023 18:36
@AlexWaygood
AlexWaygood requested review from Fidget-Spinner, JelleZijlstra and gvanrossum as code owners March 31, 2023 18:36
@bedevere-bot bedevere-bot mentioned this pull request Mar 31, 2023
Performance of typing._ProtocolMeta._get_protocol_attrs and isinstance #74690
Closed
@bedevere-bot bedevere-bot added the awaiting core review label Mar 31, 2023
@AlexWaygood

AlexWaygood commented Mar 31, 2023

Copy link
Copy Markdown
Member Author

May once again be of interest to @leycec and @posita :)

posita reacted with hooray emoji posita reacted with heart emoji posita reacted with eyes emoji
All reactions
  • 🎉 1 reaction
  • ❤️ 1 reaction
  • 👀 1 reaction

Sorry, something went wrong.

Uh oh!

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

carljm
carljm approved these changes Mar 31, 2023
View reviewed changes

@carljm carljm left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Looks fine to me.

Given @hauntsaninja 's feedback in #103141 , are you planning to land a single news entry for this and that one and #103034 that summarizes the changes and the overall perf impact?

Sorry, something went wrong.

Uh oh!

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

AlexWaygood reacted with rocket emoji
All reactions
  • 🚀 1 reaction
@bedevere-bot bedevere-bot added awaiting merge and removed awaiting core review labels Mar 31, 2023
hauntsaninja
hauntsaninja reviewed Mar 31, 2023
View reviewed changes
Comment thread Lib/typing.py Resolved

Uh oh!

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

hauntsaninja
hauntsaninja reviewed Mar 31, 2023
View reviewed changes

@hauntsaninja hauntsaninja left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Hooray, thanks for working on this!

Sorry, something went wrong.

Uh oh!

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

AlexWaygood reacted with heart emoji
All reactions
  • ❤️ 1 reaction
@AlexWaygood

AlexWaygood commented Mar 31, 2023

Copy link
Copy Markdown
Member Author

Given @hauntsaninja 's feedback in #103141 , are you planning to land a single news entry for this and that one and #103034 that summarizes the changes and the overall perf impact?

Yeah, I'll try to rework the NEWS entry in #103034 to summarise the changes made in the performance-related PRs as well as that PR 👍

carljm reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

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

@AlexWaygood
Revert direct __annotations__ access
d6c3b65
@AlexWaygood
AlexWaygood requested a review from hauntsaninja March 31, 2023 20:27
hauntsaninja
hauntsaninja approved these changes Mar 31, 2023
View reviewed changes

@hauntsaninja hauntsaninja left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Looks great!

Sorry, something went wrong.

Uh oh!

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

AlexWaygood reacted with heart emoji
All reactions
  • ❤️ 1 reaction
@AlexWaygood
AlexWaygood merged commit 361a3ea into python:main Mar 31, 2023
@bedevere-bot bedevere-bot removed the awaiting merge label Mar 31, 2023
@AlexWaygood
AlexWaygood deleted the micro-optimise-protocols branch March 31, 2023 20:54
This was referenced Apr 2, 2023
gh-102433: Use inspect.getattr_static in typing._ProtocolMeta.__instancecheck__ #103034
Merged
gh-74690: Document changes made to runtime-checkable protocols in 3.12 #103348
Merged
warsaw pushed a commit to warsaw/cpython that referenced this pull request Apr 11, 2023
@AlexWaygood @warsaw
pythongh-74690: Micro-optimise typing._get_protocol_attrs (python#1…
deb1c45
…03152)

Improve performance of `isinstance()` checks against runtime-checkable protocols
@AlexWaygood AlexWaygood mentioned this pull request Apr 12, 2023
Backport performance improvements to runtime-checkable protocols python/typing_extensions#137
Merged
@AlexWaygood AlexWaygood mentioned this pull request May 24, 2023
[Bug] typing_extensions.Protocol unsupported under typing_extensions ≥ 4.6.0 beartype/beartype#241
Closed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@carljm carljm carljm approved these changes
@hauntsaninja hauntsaninja hauntsaninja approved these changes
@gvanrossum gvanrossum Awaiting requested review from gvanrossum
@Fidget-Spinner Fidget-Spinner Awaiting requested review from Fidget-Spinner
@JelleZijlstra JelleZijlstra Awaiting requested review from JelleZijlstra JelleZijlstra is a code owner

Uh oh!

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

Assignees

No one assigned

Labels

3.12 only security fixes performance Performance or resource usage skip news stdlib Standard Library Python modules in the Lib/ directory topic-typing 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

@AlexWaygood @carljm @hauntsaninja @bedevere-bot
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.