2011-04-04 3 views
4

Possible en double:
Lazy Method for Reading Big File in Python?manière efficace pour lire les données en python

Je dois lire 100 Go (400 millions de lignes) de données à partir d'une ligne de fichiers en ligne. C'est mon code actuel, mais existe-t-il une méthode efficace pour le faire. Je veux dire en termes de vitesse d'exécution.

f = open(path, 'r') 

for line in f: 
    ... 

f.close() 
+0

Vous avez un seul fichier 100 Go ??? –

+2

C'est à peu près le meilleur moyen. –

+0

Incroyable. De toute évidence quelque chose ne va pas dans votre application si elle génère 100GB File :-) –

Répondre

2

Si les lignes sont d'une longueur d'octet fixe et les lignes ne doivent pas être lu un ordre particulier (vous pouvez toujours connaître le numéro de ligne), que vous pouvez facilement diviser en sous-tâches parallèles, en exécutant en m fils ultimes/processus. Chaque subtusk aurait seulement besoin de savoir où seek() et combien d'octets à read().

Dans ce cas également, il n'est pas optimal de lire ligne par ligne, car il doit rechercher \n, mais utiliser simplement read() avec une longueur fixe.

1

Si vous avez une machine à multi-cœurs, et peut utiliser Python 3.2 (au lieu de Python 2), ce serait un bon cas d'utilisation pour la concurrent.futures nouvelle fonctionnalité en Python 3.2 - en fonction du traitement que vous devez faire à chaque ligne. Si vous avez besoin que le traitement soit effectué dans l'ordre des fichiers, vous devrez probablement vous soucier de réassembler la sortie plus tard. Sinon, l'utilisation de concurrencer.futures peut programmer chaque client pour être traité dans une tâche différente avec peu d'effort. Quel est le résultat que vous devez générer à ce sujet?

Si vous pensez que vous ne pourriez pas profiter de la parallélisation du contenu de chaque ligne, la façon la plus évidente est la meilleure façon de faire: c'est ce que vous venez de faire.

Cet exemple divise le traitement en 12 sous-processus, chacun exécutant la fonction len intégrée de Python. Remplacer len pour une fonction qui reçoit la ligne en tant que paramètre et exécute tout ce que vous devez traiter sur cette ligne:

from concurrent.futures import ProcessPoolExecutor as Executor 

with Executor(max_workers=5) as ex: 
    with open("poeem_5.txt") as fl: 
     results = list(ex.map(len, fl)) 

L'appel « liste » est nécessaire pour forcer la cartographie à faire dans le « par » déclaration . Si vous n'avez pas besoin d'une valeur scalaire pour chaque ligne, mais plutôt d'enregistrer un résultat dans un fichier que vous pouvez le faire dans une boucle à la place:

for line in fl: 
    ex.submit(my_function, line) 
Questions connexes