Topic: Ottimizzare codice  (Letto 1247 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline polmdm

  • python unicellularis
  • *
  • Post: 6
  • Punti reputazione: 0
    • Mostra profilo
Ottimizzare codice
« il: Maggio 03, 2017, 21:33 »
Ciao a tutti, premetto di essere un principiante riguardo python e in generale con la programmazione, ad ogni modo mi sono cimentato nella scrittura di un programmino per raspberry che fondamentalmente legge dati da sensori, li accumula in un vettore e quindi me lo restituisce in un grafico (utilizzo matplotlib). Ora il mio timore è questo: dato che ho bisogno che il programma funzioni per qualche ora (anche 8) e i vettori (o meglio liste) vengono estesi ogni 3 secondi ho paura che il raspberry dopo una ventina di minuti saturi la ram (i vettori che attualmente genero sono almeno 6) e tutto il programma si inchiodi. Vorrei sapere se esiste un modo per rendere più efficiente l'elaborazione dati oppure se magari conviene creare un file del log dei dati raccolti e in un secondo momento andarli a leggere per usarli (se si come faccio a interpretare il file .txt come una matrice?) oppure implementare nel codice numpy per gestire i vettori (anche se non ho idea di come funzioni...) aspetto vostri consigli!

Offline Tungsteno

  • python erectus
  • ***
  • Post: 183
  • Punti reputazione: 0
    • Mostra profilo
Re:Ottimizzare codice
« Risposta #1 il: Maggio 03, 2017, 23:39 »
Mah, guarda la prima cosa che mi viene da consigliarti  è (per non rendere la cosa troppo complicata) buttare i dati direttamente in un file JSON.
Se vuoi invece rendere la cosa un attimino più elegante potresti usare un mini database tipo SQLITE che è integrato in python di default.
 

Offline polmdm

  • python unicellularis
  • *
  • Post: 6
  • Punti reputazione: 0
    • Mostra profilo
Re:Ottimizzare codice
« Risposta #2 il: Maggio 04, 2017, 11:13 »
Quindi in pratica creo un database che si aggiorna ogni secondo analogamente  a quanto fa già ma anzichè in un file txt lo metto nel database ed elaboro i dati una volta concluso tutta l'attività

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 3.020
  • Punti reputazione: 9
    • Mostra profilo
Re:Ottimizzare codice
« Risposta #3 il: Maggio 04, 2017, 11:46 »
Il punto è: se la ram del tuo raspberry non ce la fa a tenersi tutto in pancia, ovviamente devi alleggerire scaricando periodicamente su uno storage.  Il tipo di formato che vuoi usare poco importa: un database, un file txt, un file csv, un file json, un pickle, fai un po' tu. Anche dove sta fisicamente questo storage esterno dipende dai tuoi gusti: puoi attaccare un drive usb al raspberry, se puoi; oppure scarichi su un cloud; o sul disco fisso del tuo computer; su una tavoletta di cera scritta con uno stilo molto appuntito.

Ora, chiaramente la prima cosa che controllerei è se *davvero* la ram non ce la fa. Fai girare il tuo software per otto ore, e vedi un po' a che punto sta.
Poi farei magari un pensierino svogliato sulla struttura dati in cui sto registrando queste letture... voglio dire, una banale lista che si accumula va benissimo, ma certo è un po' ridondante se la lettura non cambia mai. Se leggi un sensore all'inizio e trovi che misura "42", e poi non cambia più per le restanti otto ore, alla fine ti trovi una lista con circa 10mila volte "42". Entusiasmante come un romanzo d'avventura. Forse se prevedi che i valori restano stabili a lungo, ti conviene registrare solo il momento in cui c'è un cambiamento, per occupare meno memoria.

Ma questo è solo per esercizio. La verità è che NON vuoi tenerti tutto nella ram, neanche se potessi farlo comodamente. Perché se durante la giornata qualcuno fa cadere un fermacarte di bronzo sul tuo raspberry, se ne va in fumo tutto il lavoro della giornata. La verità è che comunque vuoi "salvare" i dati prima che puoi, addirittura man mano che li leggi. Quindi, non scaricarli in una volta alla fine della giornata, ma neppure ogni ora o ogni 10 minuti, per dire. Scarica man mano che leggi.


Offline polmdm

  • python unicellularis
  • *
  • Post: 6
  • Punti reputazione: 0
    • Mostra profilo
Re:Ottimizzare codice
« Risposta #4 il: Maggio 06, 2017, 15:43 »
Ok così sarebbe fantastico: ogni riga che scrivo la salva nel file ma come posso farlo, devo creare un ciclo che apre tutte le volte il file, aggiunge una riga e poi lo chiude, giusto? Inoltre una cosa, mettiamo il file sia .txt, io salvo ogni volta una riga contenente 5 elementi. ammettiamo ora che alla fine di tutto il lavoro devo calcolare la media di tutti i valori della terza colonna, come faccio a indicare a python di prendere solo gli elementi in posizione 3 della riga?

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 3.020
  • Punti reputazione: 9
    • Mostra profilo
Re:Ottimizzare codice
« Risposta #5 il: Maggio 06, 2017, 18:33 »
> Ok così sarebbe fantastico: ogni riga che scrivo la salva nel file ma come posso farlo, devo creare un ciclo che apre tutte le volte il file, aggiunge una riga e poi lo chiude, giusto?

Tenere un file aperto invece, no?

> come faccio a indicare a python di prendere solo gli elementi in posizione 3 della riga?

questo però è un problema separato (e dipende ovviamente dal formato che scegli per persistere i dati). Risolvi un problema alla volta.

Offline polmdm

  • python unicellularis
  • *
  • Post: 6
  • Punti reputazione: 0
    • Mostra profilo
Re:Ottimizzare codice
« Risposta #6 il: Maggio 07, 2017, 12:11 »
Per il primo problema inizialmente avevo impostato il mio programma in questo modo:
-creo il file della directory voluta
-lo apro prima del ciclo che immagazzina tutti i dati provenienti dai sensori
- nel ciclo stesso scrivo la stringa di dati
-quando il programma termina chiudo il file
così facendo però basta un calo di corrente o altro per perdere tutto il file
ieri ho quindi ho pensato:
-creo il file
-apro il cliclo e apro il file all'interno del ciclo
-registro i dati dai sensori
-li scrivo sul file
-chiudo il file
-ripeto il ciclo
in questo modo se il programma viene interrotto per un qualsiasi motivo al massimo perdo solo l'ultima stringa e non tutte le altre.

Offline polmdm

  • python unicellularis
  • *
  • Post: 6
  • Punti reputazione: 0
    • Mostra profilo
Re:Ottimizzare codice
« Risposta #7 il: Maggio 07, 2017, 12:29 »
Per il secondo problema ora come ora creo un file .txt ma potrei farlo tranquillamente json o csv l'importate è che riesca a visualizzare il contenuto come se fosse una matrice di dati ed estrapolarne una colonna alla volta con python

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 3.020
  • Punti reputazione: 9
    • Mostra profilo
Re:Ottimizzare codice
« Risposta #8 il: Maggio 07, 2017, 12:53 »
> basta un calo di corrente o altro per perdere tutto il file
bravo...
Poi, aprire e chiudere un file ogni 3 secondi per un giorno intero può essere altrettanto rischioso, dipende dal sistema operativo e anche da come esattamente lo fai... Scrivere su un database elimina alcuni rischi (le scritture su un database sono atomiche per definizione), e ti aiuterebbe anche con il successivo problema della lettura e analisi dei dati.
Una buona idea, per questi programmi che devono andare per conto loro per un sacco di tempo, è costruirsi anche un robusto sistema di logging. Almeno sai cosa è successo mentre non c'eri.

Offline Tungsteno

  • python erectus
  • ***
  • Post: 183
  • Punti reputazione: 0
    • Mostra profilo
Re:Ottimizzare codice
« Risposta #9 il: Maggio 09, 2017, 16:26 »
in questo modo se il programma viene interrotto per un qualsiasi motivo al massimo perdo solo l'ultima stringa e non tutte le altre.

Se usi un raspberri potresti tranquillamente aggiungere un'alimentazione a batteria di backup (4 stilo dovrebbero bastare) e nel tuo programma potresti aggiungere una condizione che verifica lo stato della corrente e automaticamente (quando subentrano le batterie) chiude il file. Così nel caso in cui usi la corrente dalla rete elettrica puoi evitare di chiudere il file ogni volta che inserisci un dato (magari lo chiudi per sicurezza ogni mezz'ora e crei un nuovo file di log).
Non penso che ti salvi da ogni bordercase, ma perlomeno è già una buona ottimizzazione del tuo programma.

Offline bebo

  • python erectus
  • ***
  • Post: 241
  • Punti reputazione: 0
    • Mostra profilo
    • bebo_sudo's personal homepage
Re:Ottimizzare codice
« Risposta #10 il: Maggio 09, 2017, 23:06 »
Scusate, forse sono io che non ho capito bene il problema. Vi invito a contraddirmi se dico delle fesserie.

stiamo parlando di sistemi in real-time, o di file di log da qualche GBs?
perche' altrimenti non vedo un guadagno di tempo sensato nell'evitare ogni volta di aprire un file di testo per appenderci una riga. la performance cambia a causa di molti parametri, ma ad occhio penso che il tempo di apertura di un file sia sotto al decimo di secondo anche sul file system di un raspberry, spanna piu', spanna meno

Per evitare di far crescere troppo il file di log, basta controllarne il peso appena prima di aprirlo, e in tal caso crearne uno piu' aggiornato, secondo un qualche schema semplice.

Offline GlennHK

  • python sapiens sapiens
  • ******
  • Post: 1.655
  • Punti reputazione: 1
    • Mostra profilo
    • La Tana di GlennHK
Re:Ottimizzare codice
« Risposta #11 il: Maggio 10, 2017, 00:15 »
Ma usare flush?

Offline polmdm

  • python unicellularis
  • *
  • Post: 6
  • Punti reputazione: 0
    • Mostra profilo
Re:Ottimizzare codice
« Risposta #12 il: Maggio 11, 2017, 16:43 »
Ok io lo uso su Raspberry e il codice viene attivato e quindi lasciato funzionare per un tot ti tempo, che sia un'ora o otto alla fine avrò un file di log dove ci sono tutti i valori che mi interessano. Una volta concluso il programma ho bisogno che tutti i vari vettori registrati vengano presi dal programma stesso e graficati. La funzione per disegnarli la ho già impostata quello che non riesco a fare è riesumare i dati sotto forma di vettori dal file. Io penso che sia abbastanza sicuro il processo di apertura e chiusura del file di log anche perchè non ho idea di come creare un database....

Offline riko

  • python deus
  • *
  • moderatore
  • Post: 7.453
  • Punti reputazione: 12
    • Mostra profilo
    • RiK0 Tech Temple
Re:Ottimizzare codice
« Risposta #13 il: Maggio 13, 2017, 13:33 »
Scusate ma... io vedo questo tema. Rasperry. Leggere valori da sensori.
Ci arriva una richiesta alla settimana. Ora il problema e' in generale dal banale in giu', ma ovviamente insidioso. E tutti a farsi soluzioni custom (e a chiedere sempre le stesse cose).

Ora, questa roba e' molto studiata e molto standardizzata. Meta' mondo sta facendo roba non troppo diversa. Specificamente, il problema "tiro fuori delle metriche da" e' uno dei piu' comuni.

La comunita' dei system engineer, per intenderci, fa questa cosa usando tool che fanno la cosa giusta. Prima c'era nagios. Ora va di moda Prometeus. Che e' davvero un bel pezzo di software.
Perche' siccome appunto sono forti in system engineering, si rendono conto che questi tool hanno gia' l'architettura corretta.

Viceversa, altre community non hanno la visione giusta, forse perche' non vengono dal mondo Unix... ma da qualunque punto parte l'analisi (unix: un tool deve fare una e una sola cosa; hey... ma e' anche quello che la community OOP dice di una classe: una classe deve fare una e una sola cosa; ma se parti da discorsi di availability/reliability ottieni ancora una volta lo stesso risultato).

Insomma, cari ragazzi del Raspberry, non odiate voi stessi e fatevi furbi. Prendete Promotheus.

https://github.com/prometheus/prometheus

A questo punto l'unico pezzo che dovete scrivere e' il mini-agente che sta sul device. Il quale deve semplicemente esporre in qualche formato noto le metriche via HTTP. Insomma... tutto sto thread diventerebbe:

1. scrivo un coso che quando mi chiama popola un dizionario json di sei valori e lo serve.
2. configuro prometheus per leggere da quell'endpoint.

Prometheus ti gestisce la visualizzazione (in modo piu' raffinato di quello che puoi fare rapidamente con matplotlib), ti gestisce lo storage (in modo piu' efficiente e raffinato di quello che puoi fare tu) e, semmai ti venisse voglia, ti gestisce l'allarming.

Per cui invece che scrivere un affare che deve fare 3 cose, di cui due piuttosto complicate, scrivi uno script di verosimilmente 15 righe e hai una toolchain di qualita' nettamente superiore.