Nous avons rencontré un problème de performance inattendu lors de la traversée des répertoires à la recherche de fichiers à l'aide d'un modèle Wildcard. P>
Nous avons 180 dossiers chacun contenant 10 000 fichiers. Une recherche de ligne de commande en utilisant Nous avons d'abord essayé d'utiliser Profilage de notre code en utilisant indique que la grande majorité du temps d'exécution est dépensé pour ces appels. P>
Notre code est basé sur le blog suivant: p>
Nous avons trouvé que ceci soit lent, ce qui est mis à jour la fonction Quelqu'un peut-il perdre une lumière sur ce qui pourrait se tromper avec notre approche? P> dir system.io.directoryinfo.idio.directoryinfo.gefiles () code> avec searchOption.Alldirectories code> et ont maintenant essayé les appels d'API Win32 FindFirstFile () Code> et FindNextFile () code>. p>
getfiles code> pour prendre un chaîne code> modèle de recherche plutôt qu'un prédicat. P>
3 Réponses :
Vous pouvez essayer avec une implémentation de FindFirstFile code> et FindNextFile code> i une fois blogué à propos de. P>
Notre approche est très similaire à celle de ce Darin
J'ai testé ma solution et il faut 230 millisecondes pour énumérer un répertoire contenant> 100K fichiers.
Une nouvelle vitesse peut être obtenue avec FindFirstFileEx (... FindexInfobasic ...) code>
Dans notre scénario, nous avons 180 dossiers, chacun contenant environ 10 000 fichiers. La scission sur plusieurs dossiers est ce qui semble tuer la performance.
ESSAYER pro / contre ISHELLFOLDER :: EnumObjects Code> avec ShgetDataFromIDList / IShellfolder :: getattributes de code>. p>
dans mes tests à l'aide de Numérisation 20 dossiers avec ~ 300 000 fichiers ont pris 661 secondes avec FindFirstFileEx code> avec FindexInfobasic code> et Find_First_ex_large_fetch code> est beaucoup plus rapide que le fichier FindFiStfile code>. FindFirstFile 11 secondes avec FindFirstFileEx code>. Les appels ultérieurs vers les mêmes dossiers ont pris moins d'une seconde. P>
Sous Windows 7 x64 la différence entre utiliser Find_First_ex_large_fetch code> et non est 0x10000 par rapport à 0x1000 octets pour le tampon de recherche (trouvé avec IDA). FindexInfobasic code> peut être plus pertinent ici, cependant.
Mes mesures (W10 X64, SSD Disk Drive) montrent que FindFirstFileEx est marginalement (~ 14%) plus rapide que FindFirstFile. Le dossier de test avait des fichiers de 900k. Les énumérations ont pris typiquement 1,5 seconde. Sauf la toute première énumération, lorsque l'énumération prend 10 fois plus longtemps. (Pour les deux méthodes, bien sûr.)
Doivent me corriger en ce qui concerne la toute première énumération. Après de nombreux tests de référence, je peux confirmer que la première énumération (après avoir effacé le cache de disque) est a) ~ 3x plus lente dans le cas de FindFirstFileEx () (... FindexInfobasic, ... Find_First_ex_large_fetch), B) ~ 20x plus lent en cas de FindFirstFile ().
Qu'est-ce que vous utilisez pour effectuer la recherche de la ligne de commande? Pourrait-il être qu'il utilise les index de recherche Windows pour effectuer la requête plutôt que de progresser dans chaque fichier?
@Matt nous venons de faire un
dir / s code> (avez mis à jour mon message en conséquence).Semble suspect. Je doublis sérieusement que "Dir" utilise autre chose, à l'exception de FindFirstFile / FindNextFile. Peut-être que vous les abusez. Pourriez-vous fournir un extrait d'illustrer comment vous les utilisez?
@shachartooth: J'ai ajouté un lien vers un message contenant le code source que nous avons utilisé.
@Matt Dir n'utilise pas de service d'index
@Shengjiang 蒋晟 fait Directory.getFiles Méthode utilise le service d'index? Comment puis-je savoir ça?
Comparez avec ShellseearchFolder dans Windows API Code Pack et vous le saurez.