24

与正常的 foreach 循环相反,使用 lambda 表达式会为 GC 生成垃圾吗?

// Lambda version
Foos.ForEach(f=>f.Update(gameTime));

// Normal approach:
foreach (Foo f in Foos)
{
  f.Update(gameTime);
}

CLR 分析器显示我有 69.9% 的 system.Action< T > 并且我怀疑它是上述 foreach 循环的 Lamba 版本。真的吗?

编辑:我使用了 Microsoft CLR 分析器:http: //download.microsoft.com/download/4/4/2/442d67c7-a1c1-4884-9715-803a7b485b82/clr%20profiler.exehttp://msdn.microsoft .com/en-us/library/ff650691.aspx

4

2 回答 2

24

gameTime是的,如果闭包从本地范围(即在此上下文中)捕获变量,则 lambda 将创建垃圾。

例如,以下 C# 函数:

static void TestLambda(List<Foo> Foos, DateTime gameTime)
{
    Foos.ForEach(f => f.Update(gameTime));
}

将被翻译成这样:

private static void TestLambda(List<Foo> Foos, DateTime gameTime)
{
    Program.<>c__DisplayClass1 <>c__DisplayClass = new Program.<>c__DisplayClass1();
    <>c__DisplayClass.gameTime = gameTime;
    Foos.ForEach(new Action<Foo>(<>c__DisplayClass.<TestLambda>b__0));
}

请注意,生成的代码中有两个实例new,这意味着不仅Action分配了对象(闭包),而且还有保存捕获变量的对象(转义变量记录)。

于 2011-08-20T16:23:07.300 回答
0

在这种情况下,我认为您使用的是通用方法(ForEach),它将生成一个新类型(假设 Foo 是引用类型,只会生成一个新类型),并且 lambda 将被编译为常规匿名方法. 这并没有表明内存使用量有任何线性增长。

就分析器而言,您没有测量任何有关内存或 GC 的内容。您正在测量执行该方法所花费的时间,并且 lambda 不应该比“常规”方式慢很多。

于 2011-08-20T16:22:11.060 回答