2013-11-05 34 views
7

İşte kod. Dönen kırmızı kareler 5000 sıçrayan. (16x16 png) Pygame versiyonunda 30 fps ama 10 fps pire ile elde ediyorum. Bu tür bir şey için daha hızlı olmamalı mıydı?Pyglet, pygame'e göre neden bu kadar yavaş?

pygame sürümü:

import pygame, sys, random 
from pygame.locals import * 
import cProfile 

# Set FPS 
FPS = 60.0 
clock = pygame.time.Clock() 

# Set window 
WINDOWWIDTH= 800 
WINDOWHEIGHT = 600 

pygame.init() 
screen = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT)) 

screen.fill((0,0,0)) 
background = screen.copy().convert() 
image = pygame.image.load("square.png").convert() 

class Square(object): 
    def __init__(self,x,y): 
     self.x = x 
     self.y = y 
     self.v_x = random.randint(1,100) 
     self.v_y = random.randint(1,100) 
     self.v_r = random.randint(-100,100) 
     self.rotation = 0 

    def __rep__(self): 
     return "Square %d,%d"%(self.x,self.y) 

    def update(self,dt): 
     if self.x > WINDOWWIDTH: 
      self.v_x *= -1 
     elif self.x < 0: 
      self.v_x *= -1 
     if self.y > WINDOWHEIGHT: 
      self.v_y *= -1 
     elif self.y < 0: 
      self.v_y *= -1 

     self.x += self.v_x * dt 
     self.y += self.v_y * dt 
     self.rotation += self.v_r * dt 

    def draw(self): 
     screen.blit(pygame.transform.rotate(image,self.rotation),(self.x,self.y)) 


sqrs = [] 
for _ in range(5000): 
    sqrs.append(Square(random.randint(0,WINDOWWIDTH-1),random.randint(0,WINDOWHEIGHT-1))) 


def main_loop(): 
    tick = 0.0 
    elapsed = 0.0 

    while elapsed < 10.0: 
     dt = tick/1000.0 
     # Events 
     for event in pygame.event.get(): 
      if event.type == QUIT: 
       pygame.quit() 
       sys.exit() 

     # Logic 
     for s in sqrs: 
      s.update(dt) 

     # Drawing 
     screen.blit(background,(0,0)) 
     for s in sqrs: 
      s.draw() 

     pygame.display.update() 
     pygame.display.set_caption('test program FPS: %s'%(clock.get_fps())) 
     tick = clock.tick(FPS) 
     elapsed += tick/1000.0 
    pygame.quit() 

cProfile.run("main_loop()") 
i = input("...") 

pyglet sürümü: pygame için

import cProfile 
import pyglet, random 
# Disable error checking for increased performance 
pyglet.options['debug_gl'] = False 

from pyglet import clock 

clock.set_fps_limit(60) 

WINDOWWIDTH = 800 
WINDOWHEIGHT = 600 
FPS = 60.0 

batch = pyglet.graphics.Batch() 
window = pyglet.window.Window(WINDOWWIDTH,WINDOWHEIGHT) 
fps_display = pyglet.clock.ClockDisplay() 

image = pyglet.resource.image("square.png") 

class Square(pyglet.sprite.Sprite): 
    def __init__(self,x,y): 
     pyglet.sprite.Sprite.__init__(self,img = image,batch=batch) 
     self.x = x 
     self.y = y 
     self.v_x = random.randint(1,100) 
     self.v_y = random.randint(1,100) 
     self.v_r = random.randint(-100,100) 

    def update(self,dt): 
     if self.x > WINDOWWIDTH: 
      self.v_x *= -1 
     elif self.x < 0: 
      self.v_x *= -1 
     if self.y > WINDOWHEIGHT: 
      self.v_y *= -1 
     elif self.y < 0: 
      self.v_y *= -1 

     self.x += self.v_x * dt 
     self.y += self.v_y * dt 
     self.rotation += self.v_r * dt 

sqrs = [] 
for _ in range(5000): 
    sqrs.append(Square(random.randint(0,WINDOWWIDTH-1),random.randint(0,WINDOWHEIGHT-1))) 

elapsed = 0.0 

def update(dt): 
    global elapsed 
    elapsed += dt 
    if elapsed >= 10.0: 
     clock.unschedule(update) 
     window.close() 
    else: 
     for s in sqrs: 
      s.update(dt) 

@window.event 
def on_draw(): 
    window.clear() 
    batch.draw() 
    fps_display.draw() 


clock.schedule_interval(update, 1.0/FPS) 

if __name__ == '__main__': 
    cProfile.run("pyglet.app.run()") 
    c = input("...") 

Cprofile sonucu:

  5341607 function calls in 9.429 seconds 

    Ordered by: standard name 

    ncalls tottime percall cumtime percall filename:lineno(function) 
     1 0.000 0.000 9.429 9.429 <string>:1(<module>) 
    1335000 2.259 0.000 2.259 0.000 pygame-test.py:32(update) 
    1335000 1.323 0.000 5.969 0.000 pygame-test.py:46(draw) 
     1 0.772 0.772 9.429 9.429 pygame-test.py:55(main_loop) 
     1 0.000 0.000 9.429 9.429 {built-in method exec} 
     267 0.020 0.000 0.020 0.000 {built-in method get} 
     1 0.237 0.237 0.237 0.237 {built-in method quit} 
    1335000 3.479 0.000 3.479 0.000 {built-in method rotate} 
     267 0.013 0.000 0.013 0.000 {built-in method set_caption} 
     267 0.067 0.000 0.067 0.000 {built-in method update} 
    1335267 1.257 0.000 1.257 0.000 {method 'blit' of 'pygame.Surface' objects} 
     1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 
     267 0.000 0.000 0.000 0.000 {method 'get_fps' of 'Clock' objects} 
     267 0.001 0.000 0.001 0.000 {method 'tick' of 'Clock' objects} 

pyglet Cprofile çıkışı: - Çok uzun, bu kısmi çıkış, dolu sürüm here.

  9982775 function calls (9982587 primitive calls) in 10.066 seconds 

    Ordered by: standard name 

    ncalls tottime percall cumtime percall filename:lineno(function) 
     123 0.000 0.000 0.000 0.000 <frozen importlib._bootstrap>:1596(_handle_fromlist) 
     1 0.000 0.000 10.067 10.067 <string>:1(<module>) 
     11 0.000 0.000 0.000 0.000 __init__.py:1055(_ensure_string_data) 
     11 0.000 0.000 0.000 0.000 __init__.py:1061(_get_gl_format_and_type) 
     58 0.000 0.000 0.000 0.000 __init__.py:1140(clear) 
     75 0.000 0.000 0.012 0.000 __init__.py:1148(dispatch_event) 
     1 0.000 0.000 10.067 10.067 __init__.py:115(run) 
    ... 
     1 0.000 0.000 0.000 0.000 lib.py:124(decorate_function) 
    1108 0.005 0.000 0.005 0.000 lib_wgl.py:80(__call__) 
    285000 1.409 0.000 9.872 0.000 pyglet-test.py:29(update) 
     58 0.105 0.002 9.982 0.172 pyglet-test.py:49(update) 
    ... 
    855000 5.436 0.000 7.551 0.000 sprite.py:378(_update_position) 
    285000 0.172 0.000 2.718 0.000 sprite.py:441(_set_x) 
    851800 0.177 0.000 0.177 0.000 sprite.py:445(<lambda>) 
    285000 0.174 0.000 2.670 0.000 sprite.py:451(_set_y) 
    851115 0.155 0.000 0.155 0.000 sprite.py:455(<lambda>) 
    285000 0.182 0.000 2.692 0.000 sprite.py:461(_set_rotation) 
    285000 0.051 0.000 0.051 0.000 sprite.py:465(<lambda>) 
    ... 
    4299 0.007 0.000 0.025 0.000 vertexattribute.py:308(get_region) 
     1 0.000 0.000 0.000 0.000 vertexattribute.py:380(__init__) 
     116 0.000 0.000 0.000 0.000 vertexattribute.py:384(enable) 
     116 0.000 0.000 0.000 0.000 vertexattribute.py:387(set_pointer) 
     1 0.000 0.000 0.000 0.000 vertexattribute.py:461(__init__) 
     116 0.000 0.000 0.000 0.000 vertexattribute.py:466(enable) 
     116 0.000 0.000 0.000 0.000 vertexattribute.py:469(set_pointer) 
     1 0.000 0.000 0.000 0.000 vertexattribute.py:501(__init__) 
     116 0.000 0.000 0.000 0.000 vertexattribute.py:508(enable) 
     116 0.000 0.000 0.000 0.000 vertexattribute.py:511(set_pointer) 
     3 0.000 0.000 0.000 0.000 vertexbuffer.py:293(__init__) 
     348 0.000 0.000 0.001 0.000 vertexbuffer.py:311(bind) 
     348 0.000 0.000 0.001 0.000 vertexbuffer.py:314(unbind) 
     3 0.000 0.000 0.000 0.000 vertexbuffer.py:381(__init__) 
     348 0.001 0.000 0.004 0.000 vertexbuffer.py:388(bind) 
    4299 0.006 0.000 0.016 0.000 vertexbuffer.py:420(get_region) 
     3 0.000 0.000 0.000 0.000 vertexbuffer.py:424(resize) 
    4299 0.002 0.000 0.002 0.000 vertexbuffer.py:460(__init__) 
    855232 0.735 0.000 1.053 0.000 vertexbuffer.py:466(invalidate) 
    ... 
    855058 0.687 0.000 1.762 0.000 vertexdomain.py:581(_get_vertices) 
    ... 
    4300 0.002 0.000 0.002 0.000 {built-in method POINTER} 
    ... 
    841451 0.162 0.000 0.162 0.000 {built-in method cos} 
    ... 
2417/2415 0.000 0.000 0.000 0.000 {built-in method len} 
    855489 0.142 0.000 0.142 0.000 {built-in method max} 
    855469 0.176 0.000 0.176 0.000 {built-in method min} 
    465/407 0.000 0.000 0.000 0.000 {built-in method next} 
    ... 
    841451 0.072 0.000 0.072 0.000 {built-in method radians} 
     62 0.000 0.000 0.000 0.000 {built-in method setattr} 
    841451 0.120 0.000 0.120 0.000 {built-in method sin} 
    ... 
+0

Pire'de "giriş (...)" nedir? – ninMonkey

+0

Standart python'da giriş(). foo = input ('Lütfen bir değer girin:') ' –

cevap

2

Darboğaz, pürüzlü hareketli grafiğe dönüşüyor. Square update() yönteminde 'self.rotation' satırına yorum yaparsanız, fps'niz neredeyse iki katına çıkar.

2

Görüntülerin (ve spriteların) rastgele bir tutturucu çevresinde döndürülebilir. Eğer pyglet/sprite.py'a bakarsanız, bunun Python matematik modülünü kullanarak yapıldığını göreceksiniz, bu yüzden oldukça yavaştır. Burada OpenGL glRotate veya hatta bir verteks shader kullanarak spriteları döndürerek optimiziumasyon için yer var gibi görünüyor.

+2

Evet, bu benim de bir sonuç. Herhangi bir pratik kullanım için çok fazla standartlaştırılmamış standart pimli/hareketli görüntü oluşturma yöntemi buluyorum. Sprite._update_position çağrılarını azaltarak FPS'de% 100 artış elde edebildim. Görüyorsunuz, her yeni bir x veya y veya rotasyon ayarlandığında çağrılır; draw() yönteminden hemen önce onu çağırmak çok daha pratiktir. –

İlgili konular