Oppure

Loading
02/11/15 16:12
Roby94
Buonasera, eccoci qui con un nuovo quesito prestazionale. A parere vostro, per un implementazione di una funzione generica che necessita di un operazione ripetuta n volte che implementazione secondo voi è preferibile, un ciclo while o un metodo ricorsivo, in che casi? e sopratutto perché?
(Premetto che i ragionamenti che vorrei sentire siano riferiti a macchine single thread, quindi niente operazioni esterne al codice preso in considerazione)
Grazie.
aaa
02/11/15 16:54
nessuno
Un codice ricorsivo fa largo uso di stack che non è una risorsa abbondante. Quindi è un approccio che non va usato a cuor leggero. In molti casi è meglio l'approccio iterativo.
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
02/11/15 17:42
Roby94
D'accordo, grazie nessuno. Vorrei aggiungere una terza opzione, una funzione con ciclo interno che richiama ad ogni ciclo una seconda funzione.

Inoltre vorrei proporre una casistica che di recente ho affrontato ma a cui ancora ripenso chiedendomi se l'implementazione sia la "migliore".
In questo caso ho usato dei template per definire delle funzioni di scrittura e lettura della EEPROM di un AVR, queste si rifanno quindi a 2 algoritmi uno per leggere e uno per scrivere i dati.
I templete sono stati compilati 10 volte ciascuno. Ora continuo a pensare, in un caso in cui viene usata una sola dichiarazione del templeate nel codice il tutto funziona bene e non si notano particolari sprechi di memoria, ma se vengono richieste 2 o piu combinazioni di tipi questo codice va a ripetersi piu volte nella piccola memoria dell'AVR. Ora il principio di funzionamento è molto semplice, viene accettato il dato in ingresso ed eseguito un ciclo while in base alla sua dimensione, all'interno del ciclo viene gestita la scrittura del singolo ottetto. Cosi come è proposto forse sarebbe meglio avere una funzione che scrive un singolo ottetto e tutte le funzioni di contorno vadano a richiamare quella in un ciclo while, questo escludendo a priori la funzione ricorsiva che richiami se stessa fino all'esaurimento degli ottetti. Scegliendo questa strada mi troverei però a richiamare diverse volte una funzione all'interno di un altra, il risparmio di memoria secondo voi giustifica l'approccio? penso che la velocità di scrittura non sia un aspetto critico quanto il sovra consumo di memoria flash, voi cosa pensate?
aaa
02/11/15 21:19
TheDarkJuster
Mah in realtà quando sei sui Microcontrollori fai ciò che ti consente di risparmiare più flash. Ma nel caso in cui la flash Abbondi e i tempi computazionali siano inaccettabili corri ai ripari "sprecando" flash, mai stack, perché su quelle CPU lo stack è di 6/8 livelli, quindi un approccio ricorsivo è da evitare nel modo più assoluto.
aaa
03/11/15 0:22
ZioCrocifisso
Chiamare una funzione in un ciclo non è rilevante quanto una funzione ricorsiva, perché nel primo caso la memoria sullo stack viene allocata e deallocata ad ogni chiamata, mentre nelle funzioni ricorsive la memoria rimane tra una chiamata e l'altra. In realtà, anche se sostituisci correttamente un loop con una funzione ricorsiva, quasi sicuramente sarà efficiente quanto il loop, perché i compilatori (con le ottimizzazioni attivate) generalmente ottimizzano le tail calls, ma chiaramente non ha senso affidarsi a questa ottimizzazione se puoi essere sicuro con un loop.
aaa
03/11/15 7:14
AldoBaldo
Potrà essere solo l'impressione di uno che programma "a spanne", ma l'uso dei cicli mi dà una maggiore sensazione di chiarezza e di controllo su quel che sto facendo. In più (ma potrebbe essere che parlo a vanvera), non è che tutto quel creare e distruggere fa perdere tempo con l'esecuzione di istruzioni per allocazioni/inizializzazioni e deallocazioni "invisibili"?
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
03/11/15 13:17
TheDarkJuster
In realtà per quanto riguarda Pic e avr un ciclo e una funzione ricorsiva impiegano lo stesso tempo (se scrivi a mano in assembly il ciclo) quindi l'unica differenza è l'utilizzo di stack.
aaa
03/11/15 15:08
nessuno
@Roby94

Se devi scrivere su EEPROM la velocità non è la prima cosa a cui devi pensare, dato che è un dispositivo "lento" rispetto al resto.
In quel caso è corretto usare funzioni che trattano "stringhe" e sottofunzioni che trattano "caratteri/byte".

E' assolutamente da evitare la ricorsione nel codice micro.
Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.