per tanti dati un array grande o un file esterno ?

Salve
debbo gestire una grande mole di dati e sinceramente non so come posso fare. Non ho esperienza in arduino su questa specifica situazione.
Chiedo quindi lumi in proposito, facendo un esempio a mo' di dbase

SCENARIO
ho un "record" composto da vari campi :
matricola --> il numero univoco di riferimento
nome --> primo campo
cognome ---> secondo campo
eta ---> terzo campo
...

I records sono in tutto circa 500

lo sketch, secondo le necessità, trova il numero "matricola" e mi deve sparare a video le info nome, cognome, età etc.
La cosa dovrebbe avvenire in modo veloce, se possibile

SOLUZIONI
Cosa mi conviene fare ?
A . mettere tutto in un array e tenere tutto in memoria ?
B. mettere tutto in un file di testo e fare una ricerca leggendo il file volta per volta?
C. mettere tutto in un file di testo, leggerlo una sola volta in void setup e tenere in memoria ?
D. varie ed eventuali

Userò un ESP32 e quindi diciamo che grandi problemi di memoria non dovrei averli. Il file di testo contentente i dati è di circa 50K ma vorrei capire come gestire il tutto senza appesantire la questione.
Eventualmente qualche link di info adeguata allo specifico problema, se l'avete già in mente.

Grazie infinite

B

Se usi un ESP32 metti tutto in un file salvato sulla flash stessa dell'ESP32.
La combinazione più comune che si trova in commercio prevede una flash da 4Mbyte quindi di spazio ne hai in abbondanza.

Con la piattaforma in questione puoi usare il filesystem SPIFFS oppure il FFat (più veloce e completo rispetto a SPIFFS).

Per quanto riguarda il "quando" accedere a questi dati, dipende dalla tua applicazione. La lettura di un file di testo dal filesystem è sicuramente più lento rispetto alla RAM, ma non credo che nel tuo caso faccia poi questa gran differenza. Secondo me l'opzione 2 va più che bene.

Per quanto riguarda la memorizzazione dei dati, ci sono anche delle librerie che ti consentono di salvare un database SQLite nella flash oppure in SD esterne.

cotestatnt:
Con la piattaforma in questione puoi usare il filesystem SPIFFS oppure il FFat (più veloce e completo rispetto a SPIFFS).

Occhio cotestatnt a NON suggerire più lo SPIFFS e, anche tu, eliminalo :wink: … è stato deprecato e nelle future release delle API ESP scomparità per lasciare il posto a LittleFS che offre qualche vantaggio in più (es. cartelle nidificate) ed è, a livello di sintassi, compatibile al 100% (più o meno, basta cambiare SPIFFS con LittleFS). :wink:

Guglielmo

gpb01:
è stato deprecato e nelle future release delle API ESP scomparità

No Guglielmo, purtroppo è stato deprecato solo su piattaforma ESP8266 :slightly_frowning_face:
Gli sviluppatori del framework ESP32 (che non sono gli stessi dell’ESP8266) hanno deciso di puntare su FFat creando ulteriore confusione (per LittleFS ci sono delle librerie esterne volendo), ma per ora ancora non hanno del tutto abbandonato SPIFFS ahimé.

in effetti la velocità di ricerca e visualizzazione è - in questo caso - molto importante.
ecco perchè chiedevo se indicizzare mediante un array o un dbase.
adesso faccio delle prove e vedo se la velocità di recupero dati, assieme all'occupazione delle risorse, soddisfa le mie esigenze.
se no, passo al dbase sopra consigliato.
lavoro ormai solo con R3 per i test e esp32 per il resto :o quindi spiffs sta per essere abbandonato o quanto meno non utilizzato ...
conviene che inizio a vedere anche ffat, solo che ora ho tutto l'ide organizzato per spiffs ... dovrò adeguarmi.

p.s. ho solo spiffs - non posso,non voglio,non debbo usare sd

p.s. bis : FFat è compatibile per poter fare update OTA, come adesso faccio con spiffs ?

Se non ricordo male per l'OTA viene riservata una porzione di memoria indipendente dal resto quindi il filesystem usato nello sketch non dovrebbe in alcun modo influenzarne il funzionamento.

cotestatnt:
No Guglielmo, purtroppo è stato deprecato solo su piattaforma ESP8266 :slightly_frowning_face:

Vero, non avevo letto bene che si parlava solo di ESP32 ... su cui non conosco bene la situazione ... ::slight_smile:

Ma perché diavolo non uniformano le due cose ? >:( ... capisco le potenzialità di ESP32, ma ... su queste cose (file system) potrebbero fare una cosa uniforme ... :confused:

Guglielmo

gpb01:
Ma perché diavolo non uniformano le due cose ?

Magari trovassero un accordo...
La sensazione che ho io, è che il team che lavora sull'Arduino-ESP32 sia meno numeroso e meno "attivo", ma sono solo mie speculazioni.
Oltre al filesystem, ci sono anche altre cose che mi piacerebbe uniformassero primo fa tutti il WiFiClientSecure..
Su ESP8266 usano l'ottima BearSSL, per ESP32 invece un porting di MBed che è buggatissimo.

fotosettore:
in effetti la velocità di ricerca e visualizzazione è - in questo caso - molto importante.
ecco perchè chiedevo se indicizzare mediante un array o un dbase.

Beh se usi SpifFS o analoghi, e se devi cercare solamente per ID univoco (e non devi fare quindi ricerche per sottostringa o altri), potresti anche considerare una ulteriore possibilità, ossia mettere tutti i dati di ogni persona in un file separato, il cui nome coincide con l'ID:

001234.dat
001235,dat
001237.dat
...

In questo modo senza fare nessuna ricerca apriresti direttamente quel file e ti basterebbe leggere e fare il parsing della singola riga contenuta.

Temo però che il tempo (di libreria) per la ricerca 'del' file (invece che 'nel' file) diventi importante

Si, ovviamente hai ragione, è possibile, ma diciamo che dipende dalla libreria immagino, per cui al posto suo farei comunque qualche prova.

In ogni caso credo che se fatta bene, ogni libreria per filesystem indicizzi per nome file, anche se sinceramente io metterei tutto in un unico file, ordinando sequenzialmente i record per ID. Per non parlare anche di altre soluzioni che dipendono però de cosa si vuole ottenere, quanti record parliamo, e di quanti dati per record (es. un file "indice" caricato in memoria da usare per determinare l'offset e lunghezza record).

Io terrei tutto in una SD, per poter fare 'manutenzione' su un pc

Comunque vedo una bella sfida....

Stay tuned

Certo, anche io userei una SD, che poi caricherei in memoria (visto che parliamo di ESP) o quantomeno alla partenza copiarla da SD a memoria, oppure lasciare il file in SD e tenere in memoria zolo l'indice degli ID e relativo offset sul file, per "puntare" rapidamente a ciò che gli interessa. Come dicevo, di possibilità ce ne sono svariate, dipende dai requisiti di memoriza, velocità, e altro. Per questo io al posto dell'OP fare i qualche prova o benchmark per determinare la soluzione ottimale per la sua esigenza.

Io terrei tutto su un singolo file salvato su SD, allo startup mi indicizzerei gli ID in memoria con correlata la posizione nel file, potrebbe bastare il numero di riga.
In fase di ricerca, cerco l'ID in memoria e ottenuto il numero di riga lo leggo dal file e restituisco i dati.
Per 500 entrate, diciamo 2 byte per l'ID e 2 byte per il numero di riga farebbero 2k di memoria per l'indice.
3k se un int non bastasse per l'ID.

Purtroppo non ho fatto molte prove con SD per cui non conosco le velocità di un approccio di questo tipo.
Ma sicuramente la sovrastruttura di un gestore di file system dovrebbe pesare di più.

Maurizio

maubarzi:
Io terrei tutto su un singolo file salvato su SD, allo startup mi indicizzerei gli ID in memoria con correlata la posizione nel file

E' infatti quello che dicevo anche io, è il giusto compromesso tra prestazioni ed occupazione.

potrebbe bastare il numero di riga.

No, perché col numero di riga comunque devi scorrere tutto il file, a meno che non siano righe a lunghezza fissa, cosa che però ti obbliga quantomeno a "sprecare" byte. Memorizzare invece offset e lunghezza consente il massimo della rapidità di selezione e flessibilità (anche se potrebbe costringere a gestire il file con una certa attenzione, magari con un programmino che partendo da una tabella locale generi sia l'indice sia il file con i dati).

Oppure, come dicevo, fare un file per ogni record, con il nome file coincidente con l'ID, e si risolvono molti problemini :wink:

anzitutto grazie per innumerevoli info che mi state dando

come detto NON POSSO utilizzare SD perchè il device che contiene il .ino non deve avere accesso troppo facile e quindi non è prevista un qualcosa di esterno.
Vero è che è un file testo e quindi leggibile ma in ogni caso lavorerò per lo più con utOnti e quindi meno problemi si creano meglio mi sento.
Eventuali aggiornamenti si fanno via OTA sul mio server. No accessi fisici esterni.

Partendo da questo presupposto, sto creando un file unico da leggere volta per volta con ricerca fino al “found” di quello che mi serve.
Ho creato i record a lunghezza fissa proprio per evitare perdite di tempo nel cercare inizio-fine di ogni campo.
E proverò questa soluzione, per capire quanto tempo ci mette; la preferirei perchè ho tutto in un file ed è sicuramente più umanamente gestibile per eventuali aggiornamenti.

Ma l’idea del singolo file da leggere volta per volta è interessantissima e voglio provare anche quella.

Ho appurato or ora che in effetti i records sono pochi : 170
Anche i campi sono pochi : 7, di lunghezza tra i 6 e i 10 caratteri.

Vi tengo aggiornati. E’ una cosa che debbo risolvere entro un paio di gg

Si ma non puoi mica cambiarci i requisiti così, sotto ai piedi! :smiley: :smiley:

Detto questo, viste le premesse, direi appunto che se deve essere “chiuso” ossia non può avere una SD, e devi poter gestire aggiornamenti dovresti farcela a gestire tutto in memoria, ad esempio caricando i dati dal server allo startup del device, più eventuali aggiornamenti remoti ossia o in “push” (il server manda aggiornamenti ai device che sono sempre “in ascolto”) o “poll” (i device una volta o più al giorno interrogano il server per avere il numero di versione del file, e se successivo al proprio lo scaricano).

sigh ma io lo avevo detto :frowning:
"p.s. ho solo spiffs - non posso,non voglio,non debbo usare sd" ---> messaggio num 5

Verrà creata la possibilità di poter fare un poll manuale e uno automatico, sulla base della ultima data, direi ogni mese un check.

allora ...
mi posso accontentare di una lettura di un unico file che contiene tutto
ho simulato la ricerca dell'ultima riga su 200 : circa 180 ms

la lettura di un singolo file avviene invece in 30ms ma ho notato che spiffs ha due gravi problemi.
il primo è che non accetta subdir e in ogni caso se le accetta ho visto che non può contenere più di un tot di files.
il secondo è che si hanno a disposizione "solo" 10mila cicli erase/write, che per un prodotto che non deve essere smanettato e per giunta con modulo esp32 saldato su stampato risulta poco efficiente.

A questo punto occorre usare una eprom tipo 24LCxxx e (ripeto . no SD) e per i dubbi relativi a questo tipo di memoria apro un altro tread altrimenti rischio l' OT