-
-
Notifications
You must be signed in to change notification settings - Fork 164
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
Thoroughly test performance of pygame.display.update(list_of_rects) vs pygame.display.flip() #2514
Comments
OK, I made a test program using a (reasonably) modern sized display surface at 1920x1080. It seems like one of the main issues with passing a rect_list to If each rectangle is only a pixel or two in size, but there are 50 of them, then calling There is also some scaling cost depending on the area updated, so if you have some reasonably sized Rects, say 64x64, then 25 of them passed in to The best case for The other issue I'm currently seeing is that I seem to get some artifacting using the rect list that I don't see when flipping the whole display each time, but that may just be my poor coding. Performance test coding: from sys import stdout
from pstats import Stats
from cProfile import Profile
import random
import pygame
pygame.init()
display_surf = pygame.display.set_mode((1920, 1080))
NUM_CIRCLES = 25
CIRCLES_RADIUS = 32
def update_w_rects_test():
global display_surf
old_rect_list = []
for loops in range(0, 1000):
pygame.event.pump()
display_surf.fill((0, 0, 0))
new_rect_list = []
for _ in range(0, NUM_CIRCLES):
new_rect_list.append(
pygame.draw.circle(
display_surf,
pygame.Color("red"),
(random.randint(0, 1920), random.randint(0, 1080)),
CIRCLES_RADIUS,
)
)
update_rect_list = old_rect_list + new_rect_list
pygame.display.update(update_rect_list)
old_rect_list = new_rect_list.copy()
def flip_test():
global display_surf
for loops in range(0, 1000):
pygame.event.pump()
display_surf.fill((0, 0, 0))
for _ in range(0, NUM_CIRCLES):
pygame.draw.circle(
display_surf,
pygame.Color("red"),
(random.randint(0, 1920), random.randint(0, 1080)),
CIRCLES_RADIUS,
)
pygame.display.flip()
if __name__ == "__main__":
print("\nJust display.flip()")
profiler = Profile()
profiler.runcall(flip_test)
stats = Stats(profiler, stream=stdout)
stats.strip_dirs()
stats.sort_stats("cumulative")
stats.print_stats()
print("display.update() w rects")
profiler = Profile()
profiler.runcall(update_w_rects_test)
stats = Stats(profiler, stream=stdout)
stats.strip_dirs()
stats.sort_stats("cumulative")
stats.print_stats() On the basis of this I would advise that we keep the option available, but make a note in the docs for I would also de-emphasise this as a general performance optimisation in any tutorial docs we have. A full display surface Then, in the average, single screen game (no scrolling camera game can make use of this) - something like asteroids (on average 10-20 asteroids, bullets and ships) or space invaders (55 invaders) using a rect list in the most obvious way to update the moving objects would make the performance worse because of the number of rects you would be updating is too high. The only 'good' uses for this feature (where a small list of reasonably sized rects could be passed in) I can think of are unlikely to need the small performance boost in the first place. Anyone else have any good use cases - or can fix up my test program to get rid of that artefacting? |
This was a performance optimisation that was relevant twenty plus years ago, but with the passage of time, and the change to modern versions of SDL - my intuition is that it is no longer providing any performance benefit. The idea of it being effective is baked into a lot of pygame-ce functionality (with drawing and rendering functions returning rectangles for use in this performance optimisation). If we could prove it was, or was not, effective in the modern world we could make better decisions on what to optimise in the code, document in the docs and include in tutorials.
However, we should test it before taking any action. A to do list.
pygame.display.flip()
, and one that collects all the rectangles returned from the draws/blits into a list of rectangles and passes that list topygame.display.update()
.The text was updated successfully, but these errors were encountered: