Skip to content

Conversation

@Pierre-Sassoulas
Copy link
Member

Follow-up to #13724, will need a rebase on it to work (python 3.9 still in the CI on this branch).

@Pierre-Sassoulas Pierre-Sassoulas added the skip news used on prs to opt out of the changelog requirement label Sep 14, 2025
pass
else:
break
match item:
Copy link
Member

Choose a reason for hiding this comment

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

this looks interesting - whats the performance impact - i would expect match to be faster but that may be wishful thinking

Copy link
Member Author

Choose a reason for hiding this comment

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

Unfortunately we had mixed results in pylint regarding performance. What do you suggest as a benchmark ?

Copy link
Member

Choose a reason for hiding this comment

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

We need code fragments that trigger the different cases and then we need a codegen that given a number creates that many instances

Then we can observe/profile

Im not sure whether we should synthesize a ast or just text

Copy link
Member Author

Choose a reason for hiding this comment

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

A preliminary benchmark (done by claude) is not very encouraging : https://claude.ai/public/artifacts/3d4158ea-0594-4442-8b4c-975bc5a54ce1 (14% slower on my side, python 3.12 / ubuntu)

Copy link
Member

Choose a reason for hiding this comment

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

Seems worse than i hoped

Copy link
Member Author

Choose a reason for hiding this comment

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

The examples I took where specifically the one where the diff was very favorable (There's a lot of match on raw string that could be done but the performance is worse in this case as there's no index lookup creation), so I also expected better. From what I read it should be a neutral change performance wise except if isinstance were smartly grouped together with and / or to do less checks. Maybe the regression is due to microbenchmarking, maybe match is only a readability change. It's hard to find information that is not slop about this topic. (found this for example : https://discuss.python.org/t/pattern-matching-optimization-comparison-of-values-specified-through/20791)

Copy link
Member

Choose a reason for hiding this comment

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

But comparing bytecode seems like something to potentially use fir understanding our cases

Copy link
Member Author

Choose a reason for hiding this comment

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

Marc Mueller dug into the CPython implementation here (pylint specific but still relevant) : pylint-dev/pylint#10544 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

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

TLDR: the faster you want it to be the shittier it have to look:

- case ast.Expr(value=ast.Constant(value=str(doc))) if expect_docstring:
+ case ast.Expr(value=ast.Constant(value=str() as doc)) if expect_docstring:

... should be faster, etc. (isinstance is very well optimized)

Copy link
Contributor

Choose a reason for hiding this comment

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

Opened an issue for CPython: python/cpython#138912

@bluetech
Copy link
Member

This is definitely more readable.

Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks @Pierre-Sassoulas!

Comment on lines 1019 to 1022
# mypy's false positive, we're checking that the 'target' attribute exists.
v.left.target.id = pytest_temp # type:ignore[attr-defined]
Copy link
Contributor

Choose a reason for hiding this comment

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

Would probably be fixed with: python/mypy#19736

@Pierre-Sassoulas Pierre-Sassoulas force-pushed the match-case-goodies branch 2 times, most recently from 59bf241 to 9653a42 Compare September 24, 2025 06:02
@Pierre-Sassoulas
Copy link
Member Author

I added a test to fix the coverage failure. What do you think about the compromise between readability and performance @RonnyPfannschmidt ?

@RonnyPfannschmidt
Copy link
Member

I like the readability

Im wondering if mypyc would generate a win here

@Pierre-Sassoulas
Copy link
Member Author

I'm not sure I understand the mypyc comment, what are your suggesting exactly ?

@RonnyPfannschmidt
Copy link
Member

As would compiler of the rewriter get us reasonable speedup

@nicoddemus
Copy link
Member

I believe @RonnyPfannschmidt is just wondering aloud what mypyc would generate from that code, not suggesting to actually use mypyc in some way here.

@Pierre-Sassoulas from my POV please feel free to go ahead and merge! 😁

@Pierre-Sassoulas Pierre-Sassoulas merged commit a6ae78b into pytest-dev:main Sep 27, 2025
33 checks passed
@Pierre-Sassoulas Pierre-Sassoulas deleted the match-case-goodies branch September 27, 2025 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip news used on prs to opt out of the changelog requirement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants