J'essaie d'en savoir un peu plus sur LINQ en implémentant le spelling corrector de Peter Norvig en C#.Méthode LINQ pour ajouter des éléments à un dictionnaire
La première partie consiste à prendre un grand file of words (environ 1 million) et le mettre dans un dictionnaire où le key
est le mot et le value
est le nombre d'occurrences.
je le fais normalement comme ceci:
foreach (var word in allWords)
{
if (wordCount.ContainsKey(word))
wordCount[word]++;
else
wordCount.Add(word, 1);
}
Où allWords
est un IEnumerable<string>
Dans LINQ Je suis actuellement le faire comme ceci:
var wordCountLINQ = (from word in allWordsLINQ
group word by word
into groups
select groups).ToDictionary(g => g.Key, g => g.Count());
Je compare la 2 dictionnaires en regardant tous les <key, value>
et ils sont identiques, donc ils produisent les mêmes résultats.
La boucle foreach
prend 3,82 secondes et la requête LINQ prend 4,49 secondes
Je synchronisation à l'aide de la classe Chronomètre et je suis en cours d'exécution en mode RELEASE. Je ne pense pas que la performance soit mauvaise. Je me demandais juste s'il y avait une raison pour la différence. Est-ce que je fais la requête LINQ d'une manière inefficace ou est-ce qu'il me manque quelque chose?
Mise à jour: est ici l'échantillon complet de code de référence:
public static void TestCode()
{
//File can be downloaded from http://norvig.com/big.txt and consists of about a million words.
const string fileName = @"path_to_file";
var allWords = from Match m in Regex.Matches(File.ReadAllText(fileName).ToLower(), "[a-z]+", RegexOptions.Compiled)
select m.Value;
var wordCount = new Dictionary<string, int>();
var timer = new Stopwatch();
timer.Start();
foreach (var word in allWords)
{
if (wordCount.ContainsKey(word))
wordCount[word]++;
else
wordCount.Add(word, 1);
}
timer.Stop();
Console.WriteLine("foreach loop took {0:0.00} ms ({1:0.00} secs)\n",
timer.ElapsedMilliseconds, timer.ElapsedMilliseconds/1000.0);
//Make LINQ use a different Enumerable (with the exactly the same values),
//if you don't it suddenly becomes way faster, which I assmume is a caching thing??
var allWordsLINQ = from Match m in Regex.Matches(File.ReadAllText(fileName).ToLower(), "[a-z]+", RegexOptions.Compiled)
select m.Value;
timer.Reset();
timer.Start();
var wordCountLINQ = (from word in allWordsLINQ
group word by word
into groups
select groups).ToDictionary(g => g.Key, g => g.Count());
timer.Stop();
Console.WriteLine("LINQ took {0:0.00} ms ({1:0.00} secs)\n",
timer.ElapsedMilliseconds, timer.ElapsedMilliseconds/1000.0);
}
Il n'est pas possible de commenter la différence sauf si vous publiez le code de référence. – JaredPar
Je viens d'ajouter cela à la question pour vous. –