Ottimizzare il codice

Ciao a tutti

piu' che una domanda , la mia era una considerazione

Solo definire
String Testo = " ";
porta ad un dispendio di byte considerevole
abbiamo imparato ad usare char :drooling_face:

Ma anche un semplice map , di byte se ne ciuccia 300 =(
AmpIFV = ((ValS_IFV *(5.00/1024))- 2.5)/ 0.055;
//AmpIFV = map(ValS_IFV, 0, 1023, MinAmp, MaxAmp); // il risultato "dovrebbe" essere equivalente

Esiste un reference od un tutorial che spieghi come orientarsi per economizzare memoria ??
Ossia un elenco di funzioni sprecone con suggerimento su come sostituirle ??

Non credo esistano guide del genere.
Prendendo come esempio l'oggetto String, è una facilitazione per il trattamento delle stringhe, facilitazione che però paghi in termini di dimensione dello sketch.

In generale molte delle funzioni di Arduino sono consuma-risorse: semplificano la vita ai principianti ma per contro appesantiscono il codice e consumano memoria.

leo72:
In generale molte delle funzioni di Arduino sono consuma-risorse: semplificano la vita ai principianti ma per contro appesantiscono il codice e consumano memoria.

AmpIFV = ((analogRead(A0) *(5.00/1024))- 2.5)/ 0.055;
In questa versione senza definire alcuna variabile di byte se ne rispsrmiano altri 14

Come dici Tu ... comodo definire a priori perche' semplifica la vita ma se hai un progetto ben chiaro nella testa conviene scegliere la via meno facile ma sicuramente piu' "concentrata"

brunol949:
In questa versione senza definire alcuna variabile di byte se ne rispsrmiano altri 14

E' come la tendenza che hanno le persone a dichiarare le variabili tutte di tipo int anche se poi usano valori che sono ben inferiori a 255, per i quali basterebbe un tipo byte. Un esempio lapalissiano sono i cicli for. Il 90% della gente ho visto che scrive (esempio): for (int i=0; i<10; i++).... e via 2 byte di RAM quando con un byte i ne usavi solo 1. :wink:

Dovrebbe essere il compilatore a sostituire le funzioni con codice inline quando compila, altrimenti il povero programmatore impazzisce. Purtroppo spesso non è così..
Ricorda però che l'ottimizzazione precoce è la causa di tutti i mali! Avere del codice ottimizzato che non funziona non serve a niente.

Se si è già nelle fase di ottimizzazione del codice perchè non sta sul micro, mi raccomando di "misurare", ovvero verificare di quanto si è ottimizzato in dimensione dopo ogni modifica, alcune modifiche che apparentemente porterebbero vantaggi spesso "ingrandiscono" solamente il compilato, bisognerebbe conoscere molto bene il compilatore e l'assembly per ottimizzare le cose non banali.

Comunque come tips più banali ci sono naturalmente la scelta dei tipi che occupano la dimensione minore, l'unrolling dei cicli, etc.. a parte la scelta del tipo corretto il resto delle ottimizzazioni però rendono più difficile mantenere il codice, aspetto da tenere in considerazione in programmi "importanti"

Ciao

leo72:
E' come la tendenza che hanno le persone a dichiarare le variabili tutte di tipo int anche se poi usano valori che sono ben inferiori a 255, per i quali basterebbe un tipo byte. Un esempio lapalissiano sono i cicli for. Il 90% della gente ho visto che scrive (esempio): for (int i=0; i<10; i++).... e via 2 byte di RAM quando con un byte i ne usavi solo 1. :wink:

Spesso anche per definire stati che sarebbero piu' boolean
Boolean che poi occupano un byte

Ma il byte e' scomponibile / visibile come array di bit ??
Potrebbero essere 8 flag boolean che occupano lo spazio di 1 byte anziche di 8

Fantascienza .. vero ?

Fatta la "macchinetta" che legge i contatori dell'impianto fotovoltaico e dell'ENEL sto' proseguendo con la paginetta WEB da vedere sul tablet
Ecco il motivo di tutta 'sta avarizia :grin:

Nei cicli for c'è la tradizione di usare il tipo int perchè nei processori in genere corrisponde alla dimensione del bus dati (es. 32 bit sui pentium) e quindi le istruzioni su int vengono processate rapidamente in un colpo di clock.
Su Arduino int non corrisponde ad 8 bit purtroppo quindi consigli di evitarlo per i cicli for.

Ciao

Per "leggere parti" del byte in genere si fanno operazioni di XOR su di esso, è possibile definire un bit e andare a settare i singoli bit (anche con funzioni come bitSet, bitClear, etc..) però non è possibile dichiarare una variabile da meno di un bit.
Esempio:
se ti serve un flag vero/falso devi dichiarare una variabile di almeno un byte per forza
se ti servono 2-3-...-8 flag vero/falso non devi dichiarare due-3-...-8 variabili di un byte ma ne basta una che andrai a leggere/scrivere sui singoli bit con le funzioni apposite (o ancora meglio con XOR e company se vuoi ottimizzare la dimensione del codice)

Ciao

flz47655:
se ti servono 2-3-...-8 flag vero/falso non devi dichiarare due-3-...-8 variabili di un byte ma ne basta una che andrai a leggere/scrivere sui singoli bit con le funzioni apposite (o ancora meglio con XOR e company se vuoi ottimizzare la dimensione del codice)

Si era questo che intendevo

Ma lo faro' al momento del bisogno :slight_smile:

Grazie

Ricordo che c'era un bellissimo libro di jon bentley che si chiamava "Programming pearls" dove spiegava lamaniera migliore (anche in termini di velocità) per eseguire varii compiti via software (le cose classiche).

Se non sbaglio Multix lavorava così.

@legacy: ma non ti conveniva comprarlo da amazon.IT

risparmiavi parecchio
Ciao

legacy:
maschere per arrivare al bit.

Mi e' capitato su un PLC ( non mio ) dove gli stati erano a bit ma poi dove venivano usati era una word
Un casino di and e or per settare i bit
Fortunatamente il PLC aveva anche un set di variabili utilizzabili anche a bit ; A e' la word , A.0 A.1 i vari bit
La prima cosa che ho fatto e' stata scrivere i vari A.0 A.1 e poi copiare la word A su quella che effettivamente veniva utilizzata

Questo per dire che lavorare con le maschere per sfruttare un byte singolo al posto di 8 per dei flag boolean non e' una gran scoperta
Se ci fosse un meccanismo come quello descritto piu' sopra il discorso sarebbe diverso

Ma sempre in tema di ottimizzare
Negli esempi
int ledState = LOW; perche' non byte o boolean ?
e ancora
int ledPin = 13;

13 ci sta' benissimo in un byte ; perche' int allora

nel mio pastrocchio li ho cambiati tutti e funziona benissimo
2 byte di qua' e 2 di la'

ho comunque un mistero che non spiego
mentre gli altri variano di un paio di byte questo
byte Timer1 = 0 ;
se lo metto int aumenta di 22

e' un contatore che incrementa fino a 99 col classico Timer1++
gli altri in definitiva sono delle costanti

Sicuramente qualcuno ne capisce ; io no :roll_eyes: