2009-07-29 3 views
8

Je recherche un nombre modéré (~ 500) de dossiers pour un grand nombre (~ 200 000) de fichiers à partir d'une application .NET. J'ai espéré utiliser DirectoryInfo.GetFiles, en passant en SearchOption.AllDirectories. Cependant cette approche semble être beaucoup plus lente que d'écrire mon propre code pour itérer à travers les répertoires et faire GetFiles juste en passant dans un searchPattern.DirectoryInfo.GetFiles lent lors de l'utilisation SearchOption.AllDirectories

connexes MSDN info:

  • GetFiles(String)
    Renvoie une liste de fichiers à partir du répertoire courant correspondant searchPattern donné.
  • GetFiles(String, SearchOption)
    Renvoie une liste de fichiers du répertoire en cours correspondant au searchPattern donné et utilisant une valeur pour déterminer s'il faut rechercher dans les sous-répertoires.

Quelqu'un at-il eu une expérience similaire à cela?

Répondre

13

Ces deux fonctions sont en fait tristement célèbres pour leurs performances. La raison en est que GetFiles parcourt tout l'arborescence de répertoires et construit un tableau d'objets FileInfo, puis seulement renvoie le résultat à l'appelant. La construction de ce tableau implique beaucoup d'allocations de mémoire (je suis sûr qu'ils utilisent List en interne, mais toujours) puisque le nombre d'entrées ne peut pas être connu à l'avance.

Si vous êtes vraiment sur les performances, vous pouvez P/Invoke dans FindFirstFile/FindNextFile/FindClose, abstraire dans un IEnumerable<FileInfo> et yieldFileInfo s un à la fois.

+1

Bonne réponse et bon exemple d'utilisation du rendement. – RichardOD

1

L'approche d'Anton mentionnée en utilisant FirstFirstFile() et les méthodes natives associées a été implémentée à partir de .NET 4 via DirectoryInfo.EnumerateFiles() donc plus besoin de P/Invoke pour cela!