8
votes

Lire rapidement un grand nombre de fichiers

J'ai un grand nombre de fichiers (> 100k) relativement petits (1kb - 300 Ko) que j'ai besoin de lire et de traiter. Je suis actuellement en boucle via tous les fichiers et en utilisant fichier.readalltext pour lire le contenu, le traiter, puis lire le fichier suivant. C'est assez lent et je me demandais s'il y a un bon moyen de l'optimiser.

J'ai déjà essayé d'utiliser plusieurs threads, mais comme cela semble être io lié, je n'ai vu aucune amélioration.


4 commentaires

Quelle partie prend le plus longtemps? Chargement des fichiers ou les traiter?


@NickLarsen: Chargement des fichiers.


Même si le chargement de ceux-ci prend le plus long, le multithreading peut toujours vous donner un gain, car il peut au moins enlever (la plupart de) l'aspect de traitement du temps d'exécution total.


mettez-les à la mise à jour des fichiers et écrivez-les, ou simplement informer une sorte de fonction de l'ensemble des fichiers?


5 Réponses :


8
votes

Vous êtes très probablement correct - lire que de nombreux fichiers vont probablement limiter vos écarts potentiels car les E / S du disque seront le facteur limitant.

Cela étant dit, vous pouvez très probablement faire une faible amélioration en passant le traitement des données dans un fil séparé.

Je recommanderais d'essayer d'avoir un seul "producteur" qui lit vos fichiers. Ce fil sera io limité. Comme il lit un fichier, il peut appuyer sur le "traitement" dans un thread threadpool (. Les tâches de .NET 4 fonctionnent également pour cela) afin de faire le traitement, ce qui lui permettrait de lire immédiatement le fichier suivant.

Cela prend au moins le "temps de traitement" hors du temps d'exécution total, ce qui rend le temps total pour votre travail presque aussi rapide que le disque IO, à condition que vous ayez un noyau supplémentaire ou deux pour travailler avec ...


1 commentaires

Plusieurs producteurs écrivent-ils à une source de données sur le thread-coffre-fort augmentent-elles le débit d'accès au disque? (Curieux Pourquoi vous avez suggéré un seul producteur)



2
votes

Ce que je ferais, c'est faire le traitement dans un fil séparé. Je lirais dans un fichier et stockerais les données dans la file d'attente, puis lisez dans le fichier suivant et ainsi de suite.

Dans votre deuxième thread, demandez au fil de lire les données de cette file d'attente et de le traiter. Voir si cela aide!


0 commentaires

0
votes

C'est probablement le disque de la recherche du disque qui est le facteur limitant (c'est l'un des goulots d'étranglement les plus courants lors de la fabrication, ce qui implique généralement de nombreux types de fichiers). Les conceptions du système de fichiers muet ont une entrée de répertoire et insistent sur un pointeur sur les blocs de disque pour un fichier et que Gaurantees a un minimum de 1 recherche par fichier.

Si vous utilisez Windows, je basculerais à l'aide de NTFS (qui stocke de petits fichiers dans em> la saisie de répertoire (-> Enregistrer une recherche de disque par fichier). Nous utilisons la compression de disque, aussi , (plus de calcul mais les processeurs sont bon marché et rapide, mais moins d'espace disque -> Moins de temps de lecture); cela peut ne pas être pertinent si vos fichiers sont tous petits. Il peut y avoir un système de fichiers Linux équivalent, si c'est là que vous êtes là.

Oui, vous devez lancer un tas de threads pour lire les fichiers: p>

     forall filename in list:   fork( open filename, process file, close filename)


0 commentaires

0
votes

Je recommanderais "multithreading" de résoudre ce problème. Lorsque j'ai lu vos réponses publiques, j'ai soudainement trouvé que la réponse de Reed Copsey sera si productive. Vous pouvez trouver un exemple de cette solution préparé par elmue Sur ce lien . J'espère que cela peut être utile et merci à Reed Copsey . Cordialement


0 commentaires

0
votes

Je suis d'accord avec les commentaires de Reed et Icemanind. De plus, considérons comment augmenter l'IO du disque. Par exemple, étalez les fichiers sur plusieurs disques afin qu'ils puissent être lus en parallèle et utiliser des disques plus rapides tels que des SSDS ou peut-être un disque RAM.


0 commentaires