Mentre lavoravo su uno script completamente diverso, ho imparato che con 29 milioni di righe di testo, l'utilizzo seek()
e il funzionamento su dati bytewise è spesso più veloce rispetto a riga per riga. La stessa idea viene applicata nello script seguente: apriamo il file e invece di scorrere ciclicamente l'apertura e la chiusura del file (che può aggiungere overhead, anche se non significativo), manteniamo il file aperto e cerchiamo all'inizio.
#!/usr/bin/env python3
from __future__ import print_function
import sys,os
def error_out(string):
sys.stderr.write(string+"\n")
sys.exit(1)
def read_bytewise(fp):
data = fp.read(1024)
print(data.decode(),end="",flush=True)
while data:
data = fp.read(1024)
print(data.decode(),end="",flush=True)
#fp.seek(0,1)
def main():
howmany = int(sys.argv[1]) + 1
if not os.path.isfile(sys.argv[2]):
error_out("Needs a valid file")
fp = open(sys.argv[2],'rb')
for i in range(1,howmany):
#print(i)
fp.seek(0)
read_bytewise(fp)
fp.close()
if __name__ == '__main__': main()
Lo script stesso è piuttosto semplice in uso:
./repeat_text.py <INT> <TEXT.txt>
Per file di testo a 3 righe e 1000 iterazioni, va tutto bene, circa 0,1 secondi:
$ /usr/bin/time ./repeat_text.py 1000 input.txt > /dev/null
0.10user 0.00system 0:00.23elapsed 45%CPU (0avgtext+0avgdata 9172maxresident)k
0inputs+0outputs (0major+1033minor)pagefaults 0swaps
Lo script stesso non è molto elegante, probabilmente potrebbe essere abbreviato, ma fa il lavoro. Naturalmente, ho aggiunto alcuni bit extra qua e là, come la error_out()
funzione, che non è necessaria - è solo un piccolo tocco user-friendly.