2013-04-07 5 views
25

Sto scrivendo un gioco utilizzando le funzionalità SFML e C++ 11, come il ciclo di intervallo. Quando lavoravo sulle mappe delle tessere, ho praticamente creato una classe per ogni tessera mappa, una classe leggera che contiene semplicemente sprite, posizione e simili, e quindi ho costruito alcuni vettori annidati per rappresentare i livelli della mappa di gioco.C++ 11: Perché questo ciclo di intervalli riduce FPS di 35?

Per ottimizzare il processo di disegno di migliaia di oggetti sullo schermo alla volta, stavo semplicemente disegnando ciò che il lettore vede. Questo è andato bene.

Ho il seguente metodo che rende la mappa di gioco, la condizione ritorna fondamentalmente vero se la posizione tessera è entro i confini della fotocamera

void gameMap::render(sf::RenderWindow &winMain, sf::Vector2f offset) { 
     for(vector<int> vec1 : backgroundData) 
      for(int i : vec1) 
       if(collides(i.pos, offset) 
       myWindow.draw(i.sprite); 

    } 

funziona bene, però in-game sto ottenendo 30 FPS o meno e un sacco di movimento approssimativo. Ma ciò che mi sorprende è che il codice muggito fa la stessa cosa, rende la stessa quantità di sprite di piastrelle, ma funziona a 65 fps e il movimento è perfettamente liscia

void gameMap::render(sf::RenderWindow &winMain, sf::Vector2f offset) { 
      for(int i = 0; i < backgroundTiles.size(); i++) 
       for(int j = 0; j < backgroundTiles[i].size(); j++) 
        if(collides(backgroundTiles[i][j].pos, offset) 
        myWindow.draw(backgroundTiles[i][j].sprite); 

     } 

perché sta succedendo questo? Il ciclo basato su intervallo C++ 11 è molto più lento della vecchia scuola? Voglio davvero sentire una risposta a questo, perché i miei occhi preferiscono sinceramente il loop basato sulla gamma, e mi dispiacerebbe scoprire che il ciclo basato sulla gamma è due volte più lento.

+4

[Non misurare le prestazioni in FPS] (http://www.opengl.org/wiki/Performance#FPS_vs._Frame_Time). – GManNickG

risposta

58

Il ciclo esterno sta eseguendo una copia di ciascun vettore contenuta in backgroundData:

for(vector<int> vec1 : backgroundData) 

Change quello di uno dei seguenti:

for(vector<int>& vec1 : backgroundData) 
    for(const vector<int>& vec1 : backgroundData) 

Questo farà vec1 in una riferimento a il vettore anziché copia. Poiché i vettori sono costosi da copiare, mentre i riferimenti sono poco costosi da utilizzare, ciò migliorerà in modo significativo le prestazioni.

Per quanto riguarda la scelta tra riferimento non const e const, utilizzerei quest'ultimo quando possibile.

Un'alternativa più generale è quello di scrivere

for(auto&& vec1 : backgroundData) 

Questo crea un riferimento automaticamente tipizzato vec1 a qualsiasi tipo backgroundData contiene. && in questo contesto termina con il collegamento vec1 a qualsiasi: riferimento di riferimento, riferimento o riferimento const, a seconda dei tipi restituiti da backgroundData. [Suggerimento per @Yakk per aver fornito questa raccomandazione]

+0

Grazie mille, sembra aver fatto il trucco. Qualche spiegazione più profonda sul perché utilizzare quest'ultimo? –

+6

@Zamri: Supponendo che tu intenda "perché usare un const-ref invece di un ref", aggiunge alla documentazione del codice e probabilmente all'ottimizzazione notare che questo ciclo non modificherà alcuno dei vettori e li guarderebbe solo. –

+0

@AndreKostur Grazie! –

Problemi correlati