Python: moyen le plus rapide de traiter un gros fichier
J'ai plusieurs 3 go de fichiers délimités par des tabulations. Il y a 20 millions de lignes de chaque fichier. Toutes les lignes doivent être traitées de façon indépendante, aucun rapport entre les deux lignes.
Ma question est, ce sera plus rapide A. la Lecture ligne par ligne à l'aide de
with open() as infile:
for line in infile:
Ou B. la Lecture du fichier dans la mémoire en morceaux et de traitement, par exemple de 250 MO à un moment?
Le traitement n'est pas très compliqué, je suis juste en saisissant une valeur dans la colonne1 à List1, colonne2 à la liste 2 etc. Peut être nécessaire d'ajouter certaines valeurs de la colonne ensemble.
J'utilise python 2.7 sur une machine linux qui a 30 go de mémoire. Texte ASCII.
Toute façon à accélérer les choses en parallèle? Droit maintenant, je suis en utilisant l'ancienne méthode et le processus est très lent. Est l'utilisation de tout CSVReader module va l'aider?
Je n'ai pas à le faire en python, toute autre langue de base de données ou utiliser les idées sont les bienvenues.
Merci.
source d'informationauteur Reise45
Vous devez vous connecter pour publier un commentaire.
Il semble que votre code est I/O bound. Cela signifie que le multitraitement ne va pas aider—si vous passez 90% de votre temps de lecture du disque, d'avoir un supplément de 7 processus en attente de la prochaine lecture ne va pas aider à quoi que ce soit.
Et, tout en utilisant un fichier CSV module de lecture (si le stdlib de
csv
ou quelque chose comme NumPy ou Pandas) peut être une bonne idée pour des raisons de simplicité, il est peu probable de faire une grande différence dans la performance.Encore, il vaut la peine de vérifier que vous avez vraiment sont I/O bound, au lieu de simplement deviner. Exécuter votre programme et voir si votre utilisation de l'UC est proche de 0% ou de près de 100% ou d'un noyau. Faire ce Amadan suggéré dans un commentaire, et d'exécuter le programme avec juste
pass
pour le traitement et voir si la coupure de 5% du temps, soit 70%. Vous pouvez même essayer de comparer avec une boucle deos.open
etos.read(1024*1024)
ou quelque chose et voir si c'est pas plus rapide.Depuis votre utilisation de Python 2.x, Python est en s'appuyant sur les C stdio bibliothèque de deviner combien de tampon à la fois, de sorte qu'il pourrait être intéressant de le forcer à tampon plus. La façon la plus simple de le faire est d'utiliser
readlines(bufsize)
pour certaines grandesbufsize
. (Vous pouvez essayer différents numéros et de les mesurer pour voir où le pic de l'est. Dans mon expérience, généralement quelque chose à partir de 64 KO-8 MO est la même, mais en fonction de votre système peut être différent—en particulier si vous êtes, par exemple, la lecture d'un réseau de système de fichiers avec grand débit, mais horrible temps de latence marais le débit-vs-temps de latence du réel physique du disque et de la mise en cache de l'OS.)Ainsi, par exemple:
Pendant ce temps, en supposant que vous êtes sur un système 64 bits, vous pouvez essayer d'utiliser
mmap
au lieu de lire le fichier en premier lieu. Ce n'est certainement pas garanti être mieux, mais il peut être mieux, en fonction de votre système. Par exemple:Un Python
mmap
est en quelque sorte d'un étrange objet, il agit comme unstr
et comme unfile
dans le même temps, de sorte que vous pouvez, par exemple, manuellement itération de la numérisation pour les retours à la ligne, ou vous pouvez appelerreadline
sur elle comme si c'était un fichier. À la fois de ceux qui vont prendre plus de traitement de Python que l'itération le fichier sous forme de lignes ou de faire des lotsreadlines
(car une boucle qui serait en C est maintenant en pur Python... mais peut-être que vous pouvez obtenir autour de que avecre
ou avec un simple Cython extension?)... mais le I/O de l'avantage de l'OS en sachant ce que vous faites avec la cartographie peut marais de la CPU inconvénient.Malheureusement, Python ne pas exposer le
madvise
appel que vous souhaitez utiliser pour ajuster les choses dans une tentative pour optimiser ce en C (par exemple, la définition explicite deMADV_SEQUENTIAL
au lieu de faire le noyau de deviner, ou de les forcer transparent huge pages)—mais vous pouvez réellementctypes
la fonction delibc
.