在功能/性能/效率方面,以下片段的区别(如果有)是什么?

时间:2015-11-07 04:56:50

标签: c# .net

假设两个代码段numToGenerateminmax相同,GetNextRandom是一种使用System.Random实例生成只需返回instance.Next(min, max)的值即可获得随机整数。

使用yield的第一个代码段:

var list = new List<int>();
while(list.Count < numToGenerate)
{
    var next = GetNextRandom(min, max);
    if (!list.Contains(next))
    {
        list.Add(next);
        yield return next;
    }
}

使用正常回报的第二个片段:

var list = new List<int>();
while(list.Count < numToGenerate)
{
    var next = GetNextRandom(min, max);
    if (!list.Contains(next))
    {
        list.Add(next);
    }
}
return list;

让我们假装这些片段是返回IEnumerable<int>的方法的一部分。两者的主要区别是什么?我应该使用哪个以及为什么?我试图理解其中的功能差异。

1 个答案:

答案 0 :(得分:1)

这取决于。您是否要消耗所有要求的值?如果没有,第一个有一些优势。例如,如果您在其上调用.Take(1),则您只进行了一次循环,并且只在列表中存储了一个值。

如果GetNextRandom是一个非常缓慢的过程,并且您希望在生成UI时将值返回到UI,那么第一个在那里有优势。

但是如果你打算消费所有这些,如果来电者只是打电话给.ToList以避免两次枚举,那么第二个可能更好,你可以调整你的回报键入IList,以便调用者可以知道他们可以直接转到任何元素,并且可以对列表进行计数而无需再次枚举。 (另见Optimize LINQ for IList

就垃圾收集而言,在第一个垃圾收集过程中,该方法完成后列表将可用于垃圾收集。在第二种情况下,调用者获取整个列表并且可以保持更长时间。

PS使用HashSet<T>如果n很大,而不是在List

之上创建自己的集合