Pages: [1] 2   Go Down
Author Topic: Calcolare lunghezza stringa... ottimizzazione?  (Read 1350 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
God Member
*****
Karma: 0
Posts: 600
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao cari!
Qualche giorno fa in un topic abbiamo visto come due codici che fanno la stessa cosa, possono arrivare ad utilizzare quantità di risorse molto diverse.
Mi sono quindi chiesta se qualcuno di voi cervelloni (non sono sarcastica) ha in mente un modo più ottimizzato per fare quello che sto facendo ora.

Premessa ed obiettivi.
Ho alcune varabili: delle float ed un unsigned long.
Invio queste variabili a pachube, singolarmente, tramite dei client.print.
Pachube però mi richiede anche di comunicare il content-length.

Per calcolare quindi la lunghezza in caratteri di tutte le variabili inviate faccio così:
converto le float con dtostrf e l'unsigned long con ltoa.
Unisco tutte le variabili così convertite in un unica stringa.
Calcolo la lunghezza della stringa con strlen.

Questo è il mio content-length.

Il codice funziona, però... probabilmente è uno spreco di risorse.
Creo una stringa e dei buffer che utilizzo in pratica solo per contare i caratteri, considerato che le variabili le invio (e preferisco fare così per questioni di formattazione della PUT) singolarmente con dei client.print.

La mia domanda è, vi viene in mente un modo diverso e migliore per ricavare la somma totale dei caratteri che compongono le mie variabili?
Al momento ho 2k liberi e 200 di FREERAM, tutto funziona alla perfezione ma se trovo il modo di liberare un po' di ram posso mettere altre cose nello sketch.

Qui sotto trovate il codice che uso ora, tutte le variabili sono locali.

 
Code:
/*----- Pachube -----*/

    // buffer per la conversione delle variabili
    char charbuffertout[6]; // t_out
    char charbufferhout[6]; // h_out
    char charbuffertin[6]; // t_in
    char charbufferhin[6]; // h_in
    char charbufferT1[6]; // T1 h20
    char charbufferT2[6]; // T2 Heat
    char charbufferluce[10]; //luce

    // conversione delle variabili in ASCII
    // conversione float dtostrf(floatVar, minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf);
    dtostrf(mydata.toutES,4,1,charbuffertout);
    dtostrf(mydata.houtES,4,1,charbufferhout);
    dtostrf(mydata.tinES,4,1,charbuffertin);
    dtostrf(mydata.hinES,4,1,charbufferhin);
    dtostrf(mydata.T2ES,4,1,charbufferT2);
    dtostrf(mydata.T1ES,4,1,charbufferT1);

    ltoa(mydata.mediaHzES,charbufferluce,10); // conversione long

    //composizione della stringa per il calcolo del Content-Length:
    char stringaTs[60] = "";
    strcat(stringaTs, charbuffertout);  // Field 1 t_out
    strcat(stringaTs, charbufferhout); // Field 2 h_out
    strcat(stringaTs, charbuffertin); // Field 3 t_in
    strcat(stringaTs, charbufferhin); // Field 4 h_in
    strcat(stringaTs, charbufferT1); // Field 5 T1 H20
    strcat(stringaTs, charbufferT2); // Field 6 T2 Heat
    strcat(stringaTs, charbufferluce); // Field 7 MediaLuce

    PgmPrint("Stringa: ");
    Serial.println(stringaTs); 
    PgmPrint("StringaTs lunghezza: ");
    Serial.println( strlen(stringaTs) ); // Lunghezza della stringa originale
 
Logged

Offline Offline
God Member
*****
Karma: 5
Posts: 873
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
int strlen(char *p)
{
        int i=0;
        while (*p++) {i++};
        return i;
}
Logged

Offline Offline
God Member
*****
Karma: 5
Posts: 873
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Umm, ad ottimizzare solo strlen non ci guadagni nulla, quello che penso io e': la soluzione va cercata altrove.
« Last Edit: March 01, 2012, 09:25:30 am by legacy » Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mi viene in mente un'idea al volo (occhio: potrebbe essere una minchiata ;-)

Invece di convertire in stringa i numeri, unirli e misurare la lunghezza della stringa risultante potresti usare un unico buffer di lunghezza tale da contenere il valore convertito più lungo, e riutilizzarlo per ogni conversione, in base a questo procedimento:
- lunghezza totale = 0;
- converti il valore in stringa usando buffer
- somma la lunghezza del buffer alla lunghezza totale
- ripeti il dal punto due per ogni valore da convertire

my 2 cents smiley
Logged

0
Offline Offline
Shannon Member
****
Karma: 117
Posts: 10101
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

confermo l'idea di riutilizzare lo stesso buffer e usare una variabile contatore gloable, così risparmi un bel pò di array.
se poi vuoi evitare la conversione (e quindi l'uso dei buffer), se il numero è intero lo dividi per 10 fino ad ottenere 0, il numero di volte che dividi per 0 va sommato al contatore globale.
Per i float si complica un pò, a priori moltilplichi per 10 fino ad ottenre il modulo della divisione per 10 = 0 oppure raggiungi il numero di cifre dopo la virgola che ti servono (metti questo controllo o rischi cicli infiniti per via dell'infinitesimo del calcolatore con i numeri float)
poi a questo punto li elabori per ottenere la lunghezza come se fossero INT +1 (il +1 è la virgola)

-pensieri a caso-
però è strano, i numeri li stai inviado come stringa no? altrimenti se li invii in formato byte sai a priori che gli int sono 2 e i float 4 + la dimensione di cioò che indica che formato sono quei byte (ma dubito che usino questo tipo di formato/ottimizzazione quelli di pachube, se non altro perchè un numero in formato byte potrebbe essere uguale a \n o a \0 creando qualche casino all'interprete dell'HTTP che usa qusti valori per capire quando termina la pagina... anche se potresti incapsularli tra " ", perdendo però molto nell'ottimizzazione di questo metodo
-fine pensieri a caso-
Logged

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
God Member
*****
Karma: 5
Posts: 873
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

    len = 0
    char stringaTs[60] = "";
    char buffergarbage[???]="";

    /* */
    dtostrf(mydata.toutES,4,1,buffergarbage);
    strcat(stringaTs, buffergarbage);  // Field 1
    len+=strlen(buffergarbage);
    /* */
    dtostrf(mydata.toutES,4,1,buffergarbage);
    strcat(stringaTs, buffergarbage);  // Field 2
    len+=strlen(buffergarbage);
    ...
    /* */
    dtostrf(mydata.xxxxx,x,x,buffergarbage);
    strcat(stringaTs, buffergarbage);  // Field x
    len+=strlen(buffergarbage);
    ....
Logged

Offline Offline
God Member
*****
Karma: 5
Posts: 873
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ottima idea, se non servono, si risparmiano tutte le stringhe intermedie.
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

   len = 0
    char stringaTs[60] = "";
    char buffergarbage[???]="";

    /* */
    dtostrf(mydata.toutES,4,1,buffergarbage);
    strcat(stringaTs, buffergarbage);  // Field 1
    len+=strlen(buffergarbage);
    /* */
    dtostrf(mydata.toutES,4,1,buffergarbage);
    strcat(stringaTs, buffergarbage);  // Field 2
    len+=strlen(buffergarbage);
    ...
    /* */
    dtostrf(mydata.xxxxx,x,x,buffergarbage);
    strcat(stringaTs, buffergarbage);  // Field x
    len+=strlen(buffergarbage);
    ....


Ma in questo modo stringaTs cresce ad ogni conversione, e ben presto supererà i 60 caratteri. In pratica hai seguito il procedimento dell'OP.

Quello che intendevo io era invece:

Code:
unsigned int totalLen;
char buf[60];    // 60 = numero a caso, calibrare in base al numero convertito più lungo + 1

totalLen = 0;

ltoa(long_value_1, buf, 10);
totalLen += strlen(buf);

ltoa(long_value_2, buf, 10);
totalLen += strlen(buf);

// ecc.

(ovviamente l'uso di variabili long è solo un esempio per illustrare il meccanismo).
Logged

Offline Offline
God Member
*****
Karma: 5
Posts: 873
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si ma alla fine la stringa finale stringaTs la dovra' pur trasmettere, altrimenti a che diamine serve tutto il meccanismo ? E allora per sfruttare la tua idea ho pensato ad un buffer temporaneo buffergarbage largo boh (largo quanto la stringa piu' lunga che esce da tutte le conversioni) che sicuramente impiega meno memoria della somma dei bufferini parziali che escono da tutte quelle conversione e di cui se ho ben e capito davvero non ce ne si fa nulla, mentre da quello che ho capito io serve la stringaTs e la sua lunghezza, il tutto da sparare fuori via rete:

send(stringaTs, strlen(stringaTs))

la function strlen(x) non la puoi ottimizzare, allora ottimizzi la procedura che porta alla costruzione della stringTs, suo parametro.
« Last Edit: March 01, 2012, 07:30:33 am by legacy » Logged

0
Offline Offline
Shannon Member
****
Karma: 117
Posts: 10101
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

guarda mamma, senza buffer  smiley-mr-green

Code:
totlaLen=0;
a=datoInt;
if (a==0)
  totlaLen+=1; //nel caso sia già 0, bisogna dimensionare per contenere lo 0
while (a > 0){
 a/=10;
 totlaLen+=1;
}
Logged

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
God Member
*****
Karma: 5
Posts: 873
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si pero' cosa te ne fai della lunghezza di stringaTs se stringaTs non ce l'hai ?
Logged

0
Offline Offline
Shannon Member
****
Karma: 117
Posts: 10101
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Invio queste variabili a pachube, singolarmente, tramite dei client.print.
Pachube però mi richiede anche di comunicare il content-length.

[...]

Creo una stringa e dei buffer che utilizzo in pratica solo per contare i caratteri, considerato che le variabili le invio (e preferisco fare così per questioni di formattazione della PUT) singolarmente con dei client.print.


la richiesta è chiara, non sono necessari i buffer  smiley-mr-green
Logged

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
God Member
*****
Karma: 5
Posts: 873
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ups la parte che non avevo letto, pardon =P
Logged

Offline Offline
God Member
*****
Karma: 5
Posts: 873
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@lesto
pero' se metti totlaLen=1
salti quell' if (a==0) totlaLen+=1; //nel caso sia già 0, bisogna dimensionare per contenere lo 0

ahaha tie' beccati questa semplificazione (e cosi' mi vendico)  smiley-mr-green
« Last Edit: March 01, 2012, 09:26:44 am by legacy » Logged

Offline Offline
God Member
*****
Karma: 0
Posts: 600
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Scrivo al volo dall'iphone...
Lesto ma quel codice funziona anche per le float?
Ad occhio mi sembra possa funzionare solo per le int.
Ma Io ho prevalentemente float!

EDIT:
E poi mi sembra che ci sia anche un altro problema...
Oltre al calcolo del punto decimale, il codice non riuscirebbe a lavorare con il segno meno di una temperatura negativa.
-12.4 sono cinque caratteri...
« Last Edit: March 01, 2012, 09:37:28 am by DanielaES » Logged

Pages: [1] 2   Go Up
Jump to: