gpt4 book ai didi

c# - 用 IEnumerable/yield 解释这种奇怪的行为

转载 作者:太空狗 更新时间:2023-10-30 00:56:12 25 4
gpt4 key购买 nike

猜猜……当 i == 0 时,这个程序需要多长时间才能产生第一个输出?应该是即时的吧?通过对 yield 的延迟评估,它应该在那之后快速连续地产生输出,对吗?

static void Main(string[] args)
{
Stopwatch stopwatch = Stopwatch.StartNew();
int i = 0;
foreach (var item in massiveYieldStatement())
{
if (i++ % 10000 == 0)
Console.WriteLine(stopwatch.ElapsedMilliseconds / 1000);
}
Console.ReadKey();
}

static IEnumerable<string> massiveYieldStatement()
{
yield return "a";
yield return "a";

.. repeat 200,000 times !!

yield return "a";
}

但事实并非如此!它会在 4 到 21 分钟内没有输出,然后很快完成 - 在一个案例中不到 60 毫秒!在那几分钟内,100% 的一个核心 CPU 被使用,并且内存使用量增加。在我遇到这种情况的实际场景中,甚至在第一次迭代发生之前就抛出了 Stackoverflow 异常!我已经在 Visual Studio 的 Debug模式下和命令提示符下的 Release模式下进行了尝试。我已经在 Windows 7 x64 和 Windows Server 2008 R2 x64 上试过了。

谁能解释一下这里发生了什么?它适合你吗?

注意:这不是真实代码:真实代码的 yield 语句要少得多,但要复杂得多。这只是最简单的复制。

最佳答案

此代码生成的程序集有几 MB 大。 yield return 是一个特殊的野兽,因为它看似简单,但 C# 编译器实际上会生成一个类(“状态机”)来实现 massiveYieldStatement 方法。我很确定您正在等待 JIT 编译器编译该类的 MoveNext() 方法(您可以使用 ildasm 验证这一点:如果您尝试打开 MoveNext() 方法,它也会花费很多时间).

关于c# - 用 IEnumerable/yield 解释这种奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8253836/

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