J'ai un fichier texte contenant 21 000 chaînes (une ligne chacune) et 500 Mo d'autres fichiers texte (codes source maily). Pour chaque chaîne, je dois déterminer si elle est contenue dans l'un de ces fichiers. J'ai écrit un programme qui fait le travail mais sa performance est terrible (cela ferait cela dans quelques jours, j'ai besoin de faire le travail en 5-6 heures maximum).
J'écris avec C #, Visual Studio 2010
J'ai quelques questions concernant mon problème: ou p>
a) Quelle approche est la meilleure? p> StreamReader r = new StreamReader(file);
string s = r.ReadToEnd();
//if(s.Contains(xxx));
5 Réponses :
Vous voulez minimiser les fichiers I / O, votre première idée est donc très mauvaise, car vous ouvriez les "autres" fichiers jusqu'à 21 000 fois. Vous voulez utiliser quelque chose en fonction du second (A1). Et quand ces autres fichiers ne sont pas trop gros, chargez-les en mémoire une fois avec ReadallText.
List<string> keys = ...; // load all strings foreach(string f in Files) { //search for each string that is not already found string text = System.IO.File.ReadAllText(f); //easy version of ReadToEnd // brute force foreach(string key in keyes) { if (text.IndexOf(key) >= 0) .... } }
Est si (text.indexof (clé)> = 0) plus vite que si (texte.contains (clé))?
@Ichi: Non, je m'attendrais à ce qu'ils soient aussi rapides.
Vous voudrez peut-être regarder la recherche Windows SDK ici P>
http://msdn.microsoft.com/ EN-US / Bibliothèque / AA965362% 28VS.85% 29.aspx P>
extrait de fil p> Directives générales d'E / S strong> p> Quels sont quelques recommandations de base pour réduire le I / O activité de votre programme et améliorant ainsi ses performances. Comme pour toutes les recommandations, il est important de mesurer la performance du code optimisée avant et après l'optimisation afin de s'assurer qu'elle devient plus rapide. P>
Si vous voulez simplement savoir si la chaîne est trouvée ou non trouvée et que vous n'avez pas besoin de faire un traitement supplémentaire, je vous suggérerais que vous n'utilisez que Grep. Grep est extrêmement rapide et conçu pour exactement ce genre de problème.
grep -f strings-file other-files...
Oui, malgré la balise [C #], cela pourrait être la meilleure approche.
Je ne connais pas avec Grep et comment cela fonctionne alors peut-être que peu d'aide comment utiliser cela?
Grep est un outil très courant dans * Nix Systems. Il y a beaucoup de documents là-bas, donc il y a tenu d'être un bon tutoriel quelque part. La commande suggérée cherche toutes les chaînes trouvées dans "Strings-File" dans n'importe lequel des "autres fichiers" et imprime toutes les lignes de correspondance dans "Autres fichiers". Il existe de nombreuses options pour changer la sortie sur ce dont vous avez besoin.
La recherche doit-elle être en temps réel sur 500 Mo de texte actuel? La raison pour laquelle je demande est parce que vous pouvez créer un index de recherche sur les fichiers texte et effectuer la recherche. Ce serait beaucoup plus rapide ... Jetez un coup d'œil à Lucene p>
lucene.net p>
Il n'a pas besoin d'être une recherche en temps réel. C'est une tâche unique. Faire et oublier ça: p
Ensuite, utilisez Lucene (je n'ai pas utilisé Windows Search SDK) pour construire un index de recherche complet et effectuer des recherches contre elle ... J'ai utilisé Lucene avant ... c'est rapide!
Devez-vous écrire le programme? Windows a FindStr intégré. Vous pouvez utiliser une boucle pour pouvoir rechercher ces autres fichiers en parallèle
Certainement pas une réponse correcte / complète, mais ne chargez pas tous les fichiers (500 Mo!) Pour chaque chaîne. Une fois que vous avez (une partie de) le fichier en mémoire, faites toutes vos actions alors.
Je voulais charger un fichier entier un par un, pas 500 Mo de fichiers à la fois.
Dans quel système d'exploitation êtes-vous sur vous, si vous êtes sur Win7, vous pouvez rechercher automatiquement dans les fichiers et son assez rapide.