gpt4 book ai didi

.net - 将项目添加到字典的 LINQ 方法

转载 作者:行者123 更新时间:2023-12-04 04:14:11 24 4
gpt4 key购买 nike

我正在尝试通过实现 Peter Norvig 的 spelling corrector 来了解更多关于 LINQ 的知识。在 C# 中。

第一部分涉及采取大file of words (大约 100 万)并将其放入字典中,其中 key是这个词和value是出现的次数。

我通常会这样做:

foreach (var word in allWords)                                                    
{
if (wordCount.ContainsKey(word))
wordCount[word]++;
else
wordCount.Add(word, 1);
}

在哪里 allWordsIEnumerable<string>
在 LINQ 中,我目前正在这样做:
var wordCountLINQ = (from word in allWordsLINQ
group word by word
into groups
select groups).ToDictionary(g => g.Key, g => g.Count());

我通过查看所有 <key, value> 来比较这两个字典。它们是相同的,所以它们产生相同的结果。
foreach循环需要 3.82 秒 并且 LINQ 查询需要 4.49 秒

我正在使用 Stopwatch 类对其进行计时,并且我正在 RELEASE 模式下运行。我不认为表现不好我只是想知道是否有差异的原因。

我是在以低效的方式执行 LINQ 查询还是遗漏了什么?

更新:这是完整的基准代码示例:
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);
}

最佳答案

LINQ 版本较慢的原因之一是因为创建了两个字典而不是一个字典:

  • (内部)来自 group by 运算符; group by 还存储每个单词。您可以通过查看 ToArray() 而不是 Count() 来验证这一点。在您的情况下,这是您实际上不需要的很多开销。
  • ToDictionary 方法基本上是对实际 LINQ 查询的 foreach,其中查询的结果被添加到新字典中。根据唯一词的数量,这也可能需要一些时间。

  • LINQ 查询稍慢的另一个原因是因为 LINQ 依赖于 lambda 表达式(Dathan 的答案中的委托(delegate)),并且与内联代码相比,调用委托(delegate)会增加少量开销。

    编辑:请注意,对于某些 LINQ 方案(例如 LINQ to SQL,但不是此处的内存 LINQ),重写查询会产生更优化的计划:
    from word in allWordsLINQ 
    group word by word into groups
    select new { Word = groups.Key, Count = groups.Count() }

    但是请注意,这并没有给你一个字典,而是一个单词序列和它们的计数。您可以将其转换为字典
    (from word in allWordsLINQ 
    group word by word into groups
    select new { Word = groups.Key, Count = groups.Count() })
    .ToDictionary(g => g.Word, g => g.Count);

    关于.net - 将项目添加到字典的 LINQ 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2118671/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com