I workd on a pygame project where the program have saved a insane amount of Objects ( 100 000 + Objects ). The script is based on big distances between each groups of objects. To make it's simple the plan is a bordeless map with a camera that moving on it. There is not a big desity of object, I mean, I don't think this will pass 500 objects per 1920 x 1080.
( and seriously, 500 object is very large)
Even with 500 objects in displayed on my screen I can have a solid 150 FPS which is very well. Unfortunately, when I run the script with more objects but in a bigger zone with less density, problems comes.
So, I make a function that check for any element in the list if the program need to display it.
for obj_x, obj_y , obj_size_x, obj_size_y in objects : # take value in a tuple in the list
if (camera.x - obj_size_x ) < obj_x < (camera.x + window.current_w ): # if it not screen on x axis if continue else it's pass to the next objects
if (camera.y - obj_size_y ) < obj_y < (camera.y + window.current_h): #same but with y
pygame.draw.rect(window.screen, (0, 0, 0), (*(obj_x - camera.x, obj_y - camera.y),*(obj_size_x, obj_size_y)), 5) # the else is displayed
Right now, this function give me solid 350 FPS wihout any objects anywhere, a 60 FPS with 2500 elements displayed on camera ( and no others forms outsides ).
But if I got a total of 25 000 elements on the map, I got 60 FPS event if not object is displayed ! It's caused by the execution time of the the if which take too much time to check if a object is on the camera or not.
But with 100 000 element, when nothing on camera, run only 25 PFS...
Here is a better way to calculate what show faster ?
You could use a data structure like a Quadtree to partition the 2-Dimensional space. The big advantage here is that you would only have to iterate over and check those objects which have a chance of being visible. All objects which spatially do not intersect with the viewport / camera are automatically culled, by virtue of the fact that they can't possibly be visible.