[Python] Ottimizzare la lettura/scrittura di grossi blocchi di dati su file.
Giovanni Porcari
giovanni.porcari a softwell.it
Sab 29 Giu 2013 08:45:53 CEST
Il giorno 28/giu/2013, alle ore 23:58, Gollum1 <gollum1.smeagol1 a gmail.com> ha scritto:
> attualmente uso questo codice (funzionante):
>
> project.source_size = 0
> block_counter = 0
> block = {}
>
> while True:
> block[block_counter] = ib_file_data_support.Block(line_args,
> project, block_counter)
> block[block_counter].data = fi.read(project.BUFFER_SIZE)
>
> # qui dovrei inserire la scrittura sul file del singolo blocco.
>
> if not block[block_counter].data:
> block.pop(block_counter)
> break
>
> # Aggiungo la dimensione del blocco alla dimensione del file sorgente.
> project.source_size += len(block)
>
> # Eseguo tutti i processi che devo sul file del singolo blocco.
>
> # ELimino il blocco di dati elaborato.
> block[block_counter].data = None
>
> # Incremento il contatore di blocco e leggo il prossimo blocco.
> block_counter += 1
>
Premesso che non ho assolutamente chiaro che cosa tu debba fare e che il mio stile di
programmazione python non è detto che sia considerato valido/standard/leggibile,
ho cercato di rifattorizzare il tuo codice come lo scriverei io.
class Block(object):
def __init__(self,data):
self.data=data
def foo(self):
#comando foo di blocco
def bar(self):
#comando bar di blocco
#
#
def __len__(self):
return len(self.data)
def clear_data(self):
self.data=None
class Project(object):
def __init__(self,fi,buffer_size=1):
self.fi=fi
self.buffer_size=buffer_size
def reset(self):
self.source_size=0
self.block_counter = 0
self.blocks={}
def all_blocks(self):
data=True
while data
data=self.fi.read(self.buffer_size)
yield Block(data)
def run(self):
self.reset()
for counter,block in enumerate(self.all_blocks()):
self.source_size+=len(block)
self.process_block(block)
self.store_block(block,counter)
def process_block(self,block):
block.foo()
if ....:
block.bar()
.....
.....
def store_block(self,block,counter):
block.clear_data()
self.blocks[counter]=block
if __name__=='__main__':
p=Project(fi,bufferSize=1)
p.run()
In pratica ogni istanza di Block riceve i dati, li sa processare secondo diversi comandi
e li sa cancellare.
La classe Project invece viene instanziata con fi e dimensione buffer.
L'oggetto p al comando run si resetta dei contatori, prende i blocchi, li elabora e li mette nel dizionario.
Il metodo all_blocks è un generatore che si occupa di leggere i dati e restituire il Block con i dati ricevuti.
Ovviamente il tutto NON testato, scritto alla c..zo e senza nessuna pretesa che sia il modo migliore.
Ciao
G.
Maggiori informazioni sulla lista
Python