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

Rewrite sprite collision functions #3209

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

Conversation

aatle
Copy link
Contributor

@aatle aatle commented Nov 3, 2024

The current sprite collision functions code has some code repetition. This implementation structures it differently, which has a few effects.

  • If dokill is true in spritecollide or groupcollide, the sprites are killed after all colliding sprites have been determined, instead of during iteration (should be unnoticeable)
  • As a consequence of the previous thing, in these cases, iteration over group.sprites() is replaced by iteration over group itself, resulting in the following:
    • Avoids a list copy of the group, improving performance slightly in around 1/8 of possible cases
    • It is no longer an error to use a non-group iterable of sprites here (already no error if dokill is False)
      • I advocate for typing the sprite collide functions as supporting all iterables of sprites, instead of just sprite groups
    • "Old-style" groups that don't support iteration raise error now here (already errors if dokill is False)
  • It is now easy to implement an ignore_self parameter, e.g., with the new structure

Performance tested in 3.13.0, no regression (similar performance).
Renamed a few local variables for clarity.

@aatle aatle requested a review from a team as a code owner November 3, 2024 03:20
@yunline yunline added Code quality/robustness Code quality and resilience to changes sprite pygame.sprite labels Nov 3, 2024
@Starbuck5
Copy link
Member

Starbuck5 commented Nov 3, 2024

I heard somewhere (can't find a back reference) that the old "pull out a bound function into a local variable" trick is actually slower in the most recent versions of Python, I'd be interested to see you look into it with this case.

EDIT: Found it-- https://youtu.be/z0-4EwIFeJo?si=sTOUIHgumGYGiyZl&t=1112

@aatle
Copy link
Contributor Author

aatle commented Nov 3, 2024

Thanks. I looked into it and found no noticeable performance increase nor penalty from either using sprite_rect.colliderect instead of sprite_rect_collide or spritecollide global instead of sprite_collide_func local, on python 3.13.0.
The most likely thing is that the impact is very minimal. The talk mentions that for pure python methods, the cached method may still be faster by 3% on 3.11.

Since I saw no performance increase from removing the cached methods/functions, I will leave it in just in case python 3.9 or 3.10 needs it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Code quality/robustness Code quality and resilience to changes sprite pygame.sprite
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants