2012-08-04 6 views
1

J'essaie de lire certains fichiers dans un répertoire contenant 10 fichiers texte. Avec le temps, le nombre de fichiers augmente, et la taille totale à partir de maintenant tourne autour de 400 Mo.Lecture d'un gros fichier avec Python

contenu du fichier est au format:

student_name:student_ID:date_of_join:anotherfield1:anotherfield2 

Dans le cas d'un match, je dois imprimer toute la ligne. Voici ce que j'ai essayé.

findvalue = "student_id" #this is users input alphanumeric 
directory = "./RecordFolder" 
for filename in os.listdir(directory): 
    with open(os.path.join(directory, filename)) as f: 
     for line in f: 
      if findvalue in line: 
       print line 

Cela fonctionne, mais cela prend beaucoup de temps. Comment puis-je réduire le temps d'exécution?

+0

Si vous ne lisez que séquentiellement, vous pouvez utiliser [fichiers mappés en mémoire] (http://en.wikipedia.org/wiki/Memory-mapped_file). –

+2

Définir beaucoup de temps :) Dans mon cas, un exemple similaire prend environ 0,392s sur un fichier de 120M. Donc, devrait prendre environ 1.2s sur un fichier de 400M. La seule différence entre votre code et le mien est que j'ouvre explicitement le fichier en mode 'r'ead-only'. – favoretti

+0

Non, cela prend environ 5 min:/pour moi – Whiskey

Répondre

1

IO est notoirement lent par rapport au calcul, et étant donné que vous avez affaire à de gros fichiers, il est probablement préférable de traiter les fichiers ligne par ligne. Je ne vois pas de moyen facile de l'accélérer en Python. En fonction de la fréquence de vos "hits" (c.-à-d. findvalue in line), vous pouvez décider d'écrire dans un fichier afin de ne pas être ralenti par la sortie de la console, mais s'il y a relativement peu d'éléments trouvés, Ne faites pas beaucoup de différence.

Je pense que pour Python, il n'y a rien d'évident et de majeur à faire. Vous pouvez toujours explorer d'autres outils (tels que grep ou bases de données ...) comme approches alternatives.

PS: Pas besoin pour le else:pass ..

+0

@downvoter Un downvote *** sans *** explication n'aide * personne * (OP, SO ou moi) .. Je suis toujours heureux de corriger les erreurs ou d'améliorer une réponse, mais cela nécessite * rétroaction constructive *, à savoir , plus qu'un clic anonyme. – Levon

+0

Vous n'avez pas vraiment répondu à la question de OP. Vous venez de répéter le problème. Vos modifications rendent certainement la réponse plus productive, donc je supprime mon downvote. – blz

4

Lorsque textfiles deviennent trop lent, vous devez commencer à regarder les bases de données. L'un des principaux objectifs des bases de données est de gérer intelligemment les E/S à partir du stockage de données persistantes.

En fonction des besoins de votre application, SQLite peut convenir. Je suppose que c'est ce que vous voulez, étant donné que vous ne semblez pas avoir un ensemble de données gargantuesque. À partir de là, il suffit de faire des appels d'API de base de données et de permettre à SQLite de gérer les recherches - c'est tellement mieux que vous!

Si (pour une raison étrange) vous vraiment ne voulez pas utiliser une base de données, alors envisager de plus loin de briser vos données dans un arbre, si possible. Par exemple, vous pourriez avoir un fichier pour chaque lettre de l'alphabet dans lequel vous mettez les données des étudiants. Cela devrait réduire le temps de bouclage puisque vous réduisez le nombre d'étudiants par fichier. C'est un hack rapide, mais je pense que vous perdrez moins de cheveux si vous allez avec une base de données.

Questions connexes