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

Optimize correct colordict entries #3297

Merged
merged 3 commits into from
Jan 22, 2025

Conversation

damusss
Copy link
Member

@damusss damusss commented Jan 19, 2025

as @Starbuck5 noticed string methods are called even if the color name existed raw in the color dictionary. This PR adds a fast path when that is the case. I tested with timeit before and after this PR and correct names got a major performance increase (from 5.5 to 1.8) while other cases are basically left unchanged. I believe a fast path should also be considered for hex colors, but it's beyond the scope of this PR. MRE:

import pygame
import timeit

# change the string for different cases
print(timeit.timeit("pygame.Color('white')", globals=globals(), number=10_000_000))

# OLD
# correct: 5.5-5.8
# hex: 8-8.2
# case: 5.6-5.8
# space: 5.9+

# NEW
# correct: 1.8-1.9
# hex: 8-8.2
# case: 5.7-5.9
# space: 6+

@damusss damusss added Performance Related to the speed or resource usage of the project color pygame.color labels Jan 19, 2025
@damusss damusss requested a review from a team as a code owner January 19, 2025 11:51
Copy link
Member

@ankith26 ankith26 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 for the PR 🎉

Copy link
Member

@Starbuck5 Starbuck5 left a comment

Choose a reason for hiding this comment

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

Nice work, you turned me complaining about something into something productive! I did not have this in mind at all.

I tested with set_at to get an example of it doing something real (but also cheap).

import time
import pygame

pygame.init()

screen = pygame.Surface((300,300))

start = time.time()
for _ in range(1000000):
    screen.set_at((4,35), "red")
print(time.time() - start)

This went from 0.67 seconds to 0.29 seconds, a more than 2x boost.

Saving 0.38 seconds over a million reps means this saves 380 nanoseconds per call. If we assume the mapped tuple is absolutely zero color mapping cost there are only 120 nanoseconds left to save.

For the curious, using a mapped color was 0.17 seconds, using a 3 element tuple took 0.25 seconds, using a 4 element tuple took 0.26 seconds, and using a hex string took 1.1 seconds.

@ankith26 ankith26 merged commit aac3b96 into pygame-community:main Jan 22, 2025
25 checks passed
@damusss damusss added this to the 2.5.3 milestone Jan 23, 2025
@damusss damusss deleted the optimize-colordict branch January 23, 2025 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
color pygame.color Performance Related to the speed or resource usage of the project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants