PDA

View Full Version : Vector ed iteratori in C++


Unrue
21-04-2006, 12:54
Sto facendo un risolutore di labirinti in cui uso molti cicli. Per cercare di velocizzare il tutto ho usato i vector e gli iteratori del tipo:

vector<int> nodiaperti;
vector<int>::iterator iteratore_nodiaperti;

I cicli li faccio del tipo:

while(iteratore_nodiaperti!=nodiaperti.end())
{ corpo del while

iteratore_nodiaperti++;
}

Il problema è che non ho notato alcun miglioramento in termini di prestazioni ,anzi in alcuni casi il tempo di risoluzione del labirinto aumenta molto rispetto a quando usavo vettori statici e ci accedevo con un semplice indice intero. Ora mi chiedo, ma i vector, sono più lenti da scorrere rispetto a vettori di int semplici? Hanno molti metodi associati questo è vero, pero' forse perdono in velocità, boh. Premetto che il codice non dà alcun tipo di errore.

fek
21-04-2006, 22:16
Hai compilato in Debug o Release?

Unrue
21-04-2006, 22:29
Hai compilato in Debug o Release?

Ehm, che intendi? :) Ho compilato con il comando Run del Borland C++ Builder 6. Posso dirti che il programma con i vettori statici lo avviavo direttamente dal file.exe, quello con i vector lo avviavo compilandolo dal compilatore

shinya
22-04-2006, 12:53
Il problema è che non ho notato alcun miglioramento in termini di prestazioni ,anzi in alcuni casi il tempo di risoluzione del labirinto aumenta molto rispetto a quando usavo vettori statici e ci accedevo con un semplice indice intero. Ora mi chiedo, ma i vector, sono più lenti da scorrere rispetto a vettori di int semplici? Hanno molti metodi associati questo è vero, pero' forse perdono in velocità, boh. Premetto che il codice non dà alcun tipo di errore.

E' chiaro che più aggiungi livelli di astrazione, più rallenti la velocità pura. Fai un bilancio tra la velocità di cui necessiti e quanto l'astrazione ti facilita la vita. Se risparmi molto brain-time, usa costrutti di più alto livello. Altrimenti divertiti con gli array.

84seawolf
22-04-2006, 16:34
Sebbene le STL siano ottimizzate (per ottimizzate intendo buon compromesso tra velocità di elaborazione e funzioni messe a disposizione), possono capitare casi in cui è vitale una prestazione (in termini di velocità) elevata. In tal caso, se non ti servono tutte le funzioni aggiuntive messe a disposizione dalle STL, ti consiglio di utilizzare gli array statici "classici" sicuramente + veloci.

fek
23-04-2006, 01:49
Ehm, che intendi? :) Ho compilato con il comando Run del Borland C++ Builder 6. Posso dirti che il programma con i vettori statici lo avviavo direttamente dal file.exe, quello con i vector lo avviavo compilandolo dal compilatore

Puoi compilare l'eseguibile con o senza ottimizzazioni (release o debug). Con tutte le ottimizzazioni attivate il tuo codice che usa std::vector e' perfettamente equivalente alla versione che usa gli array. Senza ottimizzazioni attivate e' invece molto piu' lenta. Assicurati di compilare una versione ottimizzata.

Nel 99.9% dei casi, per te, std::vector e' piu' che efficiente e non ti capitera' mai di aver bisogno di usare gli array nativi.

Unrue
23-04-2006, 16:23
Puoi compilare l'eseguibile con o senza ottimizzazioni (release o debug). Con tutte le ottimizzazioni attivate il tuo codice che usa std::vector e' perfettamente equivalente alla versione che usa gli array. Senza ottimizzazioni attivate e' invece molto piu' lenta. Assicurati di compilare una versione ottimizzata.

Nel 99.9% dei casi, per te, std::vector e' piu' che efficiente e non ti capitera' mai di aver bisogno di usare gli array nativi.

Grazie! Questa non la sapevo.Ma , più in dettaglio, in cosa consistono queste ottimizzazioni? ciao :)

fek
23-04-2006, 21:22
Grazie! Questa non la sapevo.Ma , più in dettaglio, in cosa consistono queste ottimizzazioni? ciao :)

Le ottimizzazioni che puo' fare il compilatore sono tantissime. Nel tuo caso quella piu' importante e' l'"inlining": al posto di fare chiamate ai metodi della classe vector, il compilatore e' in grado (in particolari condizioni) di prendere il codice di questi metodi e metterlo direttamente al punto di chiamata, evitando di chiamare il metodo. Il codice che ne esce e' esattamente uguale a quello che tu avresti scritto senza usare la classe vector.

71104
23-04-2006, 21:45
Le ottimizzazioni che puo' fare il compilatore sono tantissime. Nel tuo caso quella piu' importante e' l'"inlining": al posto di fare chiamate ai metodi della classe vector, il compilatore e' in grado (in particolari condizioni) di prendere il codice di questi metodi e metterlo direttamente al punto di chiamata, evitando di chiamare il metodo. Il codice che ne esce e' esattamente uguale a quello che tu avresti scritto senza usare la classe vector. ho esperienza passata col BCB (soprattutto con Delphi in realtà), ma da quel poco che ricordo non è come in Visual C++ dove puoi scegliere la configurazione cambiando al volo tutte le opzioni per la command line del compilatore; là si compila sempre allo stesso modo.

Unrue
23-04-2006, 22:48
Le ottimizzazioni che puo' fare il compilatore sono tantissime. Nel tuo caso quella piu' importante e' l'"inlining": al posto di fare chiamate ai metodi della classe vector, il compilatore e' in grado (in particolari condizioni) di prendere il codice di questi metodi e metterlo direttamente al punto di chiamata, evitando di chiamare il metodo. Il codice che ne esce e' esattamente uguale a quello che tu avresti scritto senza usare la classe vector.


Dunque, se non ho capito male, se in un programma so che una funzione verrà chiamata molte volte, conviene dichiararla inline vero? Questo pero' se il corpo della funzione non è troppo grosso. Quali sono le controindicazioni?

84seawolf
24-04-2006, 09:16
come sempre ci sono dei compromessi: utilizzando inline certamente l'esecuzione di funzioni è molto + veloce....

ho detto esecuzione perchè non vengono effettuate chiamate (è come se tu copiassi ogni volta il codice della funzione nel punto in cui viene utilizzata). Tuttavia, specialmente se utilizzi numerose funzioni abbastanza corpose (e le utilizzi spesso), ciò può provocare un'occupazione di memoria notevole.

Scegli in base alle tue specifiche esigenze.

shinya
24-04-2006, 09:18
Dunque, se non ho capito male, se in un programma so che una funzione verrà chiamata molte volte, conviene dichiararla inline vero? Questo pero' se il corpo della funzione non è troppo grosso. Quali sono le controindicazioni?

Non usarlo molto se devi fare una cosa tipo questa :)
http://www.theprodukkt.com/kkrieger.html
(per chi non ha mai visto un gioco che sta in 96kb!)

Unrue
24-04-2006, 12:25
Non usarlo molto se devi fare una cosa tipo questa :)
http://www.theprodukkt.com/kkrieger.html
(per chi non ha mai visto un gioco che sta in 96kb!)

Come può un gioco in grafica tridimensionale stare in soli 96kb? :confused:

Unrue
24-04-2006, 12:29
come sempre ci sono dei compromessi: utilizzando inline certamente l'esecuzione di funzioni è molto + veloce....

ho detto esecuzione perchè non vengono effettuate chiamate (è come se tu copiassi ogni volta il codice della funzione nel punto in cui viene utilizzata). Tuttavia, specialmente se utilizzi numerose funzioni abbastanza corpose (e le utilizzi spesso), ciò può provocare un'occupazione di memoria notevole.

Scegli in base alle tue specifiche esigenze.

Nel mio progetto ho una funzione di circa 20 righe che viene chiamata un casino di volte. Ora provo a farla inline :)

shinya
24-04-2006, 12:39
Come può un gioco in grafica tridimensionale stare in soli 96kb? :confused:

Ci sta.
Ma devi essere fuso di testa.

fek
24-04-2006, 14:08
Dunque, se non ho capito male, se in un programma so che una funzione verrà chiamata molte volte, conviene dichiararla inline vero? Questo pero' se il corpo della funzione non è troppo grosso. Quali sono le controindicazioni?

Si', anzi Ni'.

Come regola generale non dichiarare mai nulla inline mentre scrivi il codice, soprattutto in progetti molto grossi, perche' per svariati motivi tende a rallentare di molto la compilazione e... tanto non cambia nulla a livello di velocita' nel 99.99% dei casi se hai un buon compilatore.

La direttiva 'inline' e' solo un consiglio che dai al compilatore e come tutti i consigli il compilatore puo' ignorarli e spesso e volentieri lo fa (secondo alcune metriche sue). Se dichiari inline un metodo molto corposo, sicuramente il compilatore lo ignorera'. Inoltre i compilatori di ultima generazione sono in grado di mettere inline anche metodi che tu non hai dichiarato inline, quando ci sono le condizioni.

In conclusione: non dichiarare nulla inline, e usa un ottimo compilatore. Avrai il meglio dai due mondi.

71104
24-04-2006, 14:10
Ci sta.
Ma devi essere fuso di testa. ci sta ma non funziona più che altro: da me non parte, non penso sia un problema di requisiti.

71104
24-04-2006, 14:14
Nel mio progetto ho una funzione di circa 20 righe che viene chiamata un casino di volte. Ora provo a farla inline :) 20 righe sono già troppe per l'inline; l'inlining (se non addirittura una bella macro) si usa quando hai del codice che viene usato spesso è che è talmente ridotto da non valere la pena della creazione di uno stack frame e del codice di chiamata a funzione.
per esempio su MFC (un popolare framework a oggetti per la programmazione Win32) molti metodi di alcune classi altro non fanno che chiamare la funzione API Win32 omonima passandogli un handle ricavato dal this; tutti quei metodi sono inline, ed è un'ottima scelta perché se non lo fossero avresti al momento della chiamata due stack frames letteralmente identici anziché uno. e nota bene che sono tutti metodi da una sola riga di codice, perché devono solo fare la chiamata :)

shinya
24-04-2006, 14:21
ci sta ma non funziona più che altro: da me non parte, non penso sia un problema di requisiti.

Strano...io la provai a suo tempo quando uscì. Usi xp o qualcos'altro? (un mio amico usa win 2003 server e ha qualche problema con queste cose)

Comunque, sta in 96kb...quindi qualche problema di compatibilità gliela possiamo pure tollerare :)