Async IO (avançat)
Lectura de fitxers molt grans amb Generator (yield)
Section titled “Lectura de fitxers molt grans amb Generator (yield)”Els algorismes que hem vist fins ara carreguen tot el fitxer a la memòria. Això pot ser lent i ineficient quan són grans, i més en servidors d’aplicacions web.
Per això, podem utilitzar un Generator, que el que fa és anar llegint el fitxer línia per línia.
A continuació, per provar com funciona un Generador i comprovar que aquesta hipotesi és certa (que amb Genrator i yield estalviem temps i recursos), desenvoluparem un benchmark per comparar els dos enfocaments utilitzant un fitxer de 10,000 línies i 12 columnes.
import numpy as npimport time
# Funció per llegir tot el fitxer a la memòriadef read_file_all_at_once(file_path): with open(file_path, 'r') as file: lines = file.readlines() processed_lines = [line.strip() for line in lines] return processed_lines
# Funció per llegir el fitxer línia per línia amb generadordef read_file_with_generator(file_path): with open(file_path, 'r') as file: for line in file: yield line.strip()
# Generar fitxer de provanum_lines = 12000num_columns = 50data = np.random.rand(num_lines, num_columns)
file_path = 'large_file.txt'with open(file_path, 'w') as file: for row in data: file.write(','.join(map(str, row)) + '\n')
# Benchmarking sense generadorsstart_time = time.time()all_lines = read_file_all_at_once(file_path)end_time = time.time()print("Temps de lectura sense generadors:", end_time - start_time)
# Benchmarking amb generadorsstart_time = time.time()for line in read_file_with_generator(file_path): pass # Processa cada línia aquíend_time = time.time()print("Temps de lectura amb generadors:", end_time - start_time)
Resultats del Benchmarking:
Temps de lectura sense generadors: 0.05058765411376953
Temps de lectura amb generadors: 0.017226219177246094
Com veiem, el temps de lectura amb generadors és inferior, per tant és més eficient a nivell de temps.
Com es crea el Generador ?
La gràcia de la funció read_file_with_generator
és que en comptes de tenir el return
té la paraula clau yield
.
La paraula clau yield és la clau que converteix aquesta funció en un generador. En lloc de retornar un valor i sortir de la funció (com faria return), yield retorna una línia processada (sense espais en blanc al principi i al final) i suspèn l’execució de la funció. La propera vegada que es cridi next()
sobre l’iterador retornat per aquesta funció, la execució es reprèn just després del yield.
Referències consultades:
Section titled “Referències consultades:”- https://www.udacity.com/blog/2021/09/getting-started-with-try-except-in-python.html
- https://realpython.com/python-download-file-from-url/
- https://www.udacity.com/blog/2021/09/getting-started-with-try-except-in-python.html
Referències pendents d’incloure per ampliar:
Section titled “Referències pendents d’incloure per ampliar:”- https://medium.com/@technige/what-does-requests-offer-over-urllib3-in-2022-e6a38d9273d9
- https://stackabuse.com/bytes/how-to-unzip-a-gz-file-using-python/
- https://bito.ai/resources/unzip-gz-file-python-python-explained/ . https://pywombat.com/articles/shutil-python
Relatives a AsyncIO: