我正在寻找一种方法来提高PySDL2渲染大量大精灵的性能。Bellow是我的尝试,尝试尽可能多地使用硬件渲染:
import sdl2.ext as sdl2ext, sdl2
import sys
from random import randint
def run():
sdl2ext.init()
disp_mode = sdl2.video.SDL_DisplayMode()
sdl2.SDL_GetDesktopDisplayMode(0, disp_mode)
window = sdl2ext.Window('pysdl2 benchmark', size=(disp_mode.w, disp_mode.h),
flags=sdl2.SDL_WINDOW_SHOWN | sdl2.SDL_WINDOW_FULLSCREEN_DESKTOP)
window_w, window_h = window.size
window.show()
renderer = sdl2ext.Renderer(window)
factory = sdl2ext.SpriteFactory(sprite_type=sdl2ext.TEXTURE,
renderer=renderer)
spr_image = sdl2ext.image.load_image('big_sprite.png')
sprites = [factory.from_surface(spr_image) for _ in xrange(100)]
for spr in sprites:
spr.position = randint(0,160), randint(0,90)
spr.w, spr.h = spr.size
spr.dx = randint(1,16); spr.dy = randint(1,16)
renderer_spr = sdl2.ext.TextureSpriteRenderSystem(renderer)
running = True
while running:
events = sdl2ext.get_events()
for event in events:
if event.type == sdl2.SDL_QUIT:
running = False
break
renderer.clear(COLOR_CARMINE) # instance of sdl2ext.Color
renderer_spr.render(sprites)
renderer.present()
# Updating sprites positions
for spr in sprites:
if spr.x + spr.w + spr.dx > window_w or
spr.x + spr.dx < 0:
spr.dx = -spr.dx
if spr.y + spr.h + spr.dy > window_h or
spr.y + spr.dy < 0:
spr.dy = -spr.dy
spr.x += spr.dx
spr.y += spr.dy
#window.refresh()
sdl2ext.quit()
return 0
由于PySDL2的文档相当稀疏,我很好奇我是否遗漏了一些重要的内容,并且编写的代码在某种程度上是次优的。
一些快速性能建议
- 您应该首先告诉我们这个示例的当前性能。任何高于60帧/秒的画面都可以
- 使用探查器查找瓶颈
- 请注意,python循环本身就很慢。您应该找到提供类型信息和/或删除绑定检查的方法
- 像numpy这样的库可以提供帮助
更多详细信息
在kivy框架中,我们使用Cython(在有意义的地方将python编译为C)。现在,我不知道你想做什么的具体细节,所以要相信它的价值。Python循环很慢,尤其是在使用游戏循环更新精灵的情况下。
我曾经写过一篇shmup,也遇到过同样的问题。通过对该项目进行细胞化获得了最佳业绩(30%的持平收益)。然后我尝试(强烈地)键入我能键入的所有内容(再次键入cython),然后在使用探查器的同时优化了python循环。您已经删除了屏幕外的精灵(但您应该检查它是否正常工作),请注意对象创建/垃圾收集的成本。