gpt4 book ai didi

c# - 列表 与 IEnumerable

转载 作者:太空狗 更新时间:2023-10-29 21:44:40 24 4
gpt4 key购买 nike

我运行了以下控制台应用程序:

class Program
{
static void Main(string[] args)
{
int n = 10000;

Stopwatch s = new Stopwatch();
s.Start();
List<int> numbers = GetListNumber(n);
foreach (var number in numbers)
{

}
s.Stop();
Console.WriteLine(s.Elapsed);
Console.WriteLine();

s.Restart();
foreach (var number in GetEnumerator(n))
{

}
s.Stop();
Console.WriteLine(s.Elapsed);
Console.ReadKey();
}

static List<int> GetListNumber(int n)
{
List<int> numbers = new List<int>();
for (int i = 0; i < n; i++)
numbers.Add(i);
return numbers;
}

static IEnumerable<int> GetEnumerator(int n)
{
for (int i = 0; i < n; i++)
yield return i;
}
}

为了比较循环遍历集合元素所需的时间,以及使用 List 还是 IEnumerable 构建此集合更好。令我惊讶的是,List 的结果是 00:00:00.0005504,IEnumerable 的结果是 00:00:00.0016900。我期待第二种方式,IEnumerable,它会更快,因为值是动态创建的,我们不必一次添加它们中的每一个,就像在List 的情况,然后遍历它。

有人可以解释一下这个区别吗?为什么我们有这种行为而没有相反的行为。

在此先感谢您的帮助!

最佳答案

首先,您的测试方式并不能真正让您对性能差异产生有用的印象。 10000 项的迭代确实太短了;你已经可以看到这一点,因为你在几微秒内就得到了结果。相反,您应该始终尝试从中获得多秒。此外,您应该始终按顺序多次 运行相同的测试,然后取平均值。这样您就可以消除随机影响并获得更稳定的结果(另请参见 law of large numbers)。

但是,是的,迭代生成器函数可能比列表慢。这是出于不同的原因:首先,当你从一个暂停执行的函数中获取项目时,你最终会进行大量的上下文切换。我不确定这对生成器函数的优化程度如何,但你仍然必须以某种方式处理它们,所以你在那里确实会受到惩罚。

其次,列表在内部使用可根据需要动态调整大小的数组。所以最后,当你遍历一个列表时,你就是在遍历一个数组。您正在迭代内存中的一系列数字。这总是比其他任何事情都快。

最大的区别是内存方面,这应该让您考虑生成器函数而不是完整列表。创建列表时,您正在快速生成所有项目,将它们放入内存,然后再次快速迭代它们。但是您也将它们全部 放入内存中。因此,根据元素的数量,这可能意味着很大的成本。尤其是当您只需要访问一个项目一次时,这通常是不值得的。另一方面,生成器函数只需要单个项目的内存,因此在内存方面,这是非常有效的。

最后,虽然存在速度差异,但这可能无关紧要。应用程序很少会因为您决定在某处使用生成器函数而变慢。更有可能的是,您的应用程序的瓶颈在其他地方,很可能在 I/O 或网络操作中,因此在它成为问题之前您真的不应该关心它。

关于c# - 列表 <T> 与 IEnumerable<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22592916/

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