C# 是否有 Lambda =>产生垃圾?

发布于 2024-11-30 08:29:07 字数 699 浏览 1 评论 0原文

与普通的 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 循环的lambda 版本。这是真的吗?

编辑:我使用了 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

Does using a lambda expression generate garbage for the GC opposed to the normal foreach loop?

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

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

The CLR profiler shows that I have 69.9% system.Action< T > and I suspect that being the lamba version of the foreach loop as above. Is that true?

EDIT: I used the Microsoft CLR profiler: http://download.microsoft.com/download/4/4/2/442d67c7-a1c1-4884-9715-803a7b485b82/clr%20profiler.exe
or http://msdn.microsoft.com/en-us/library/ff650691.aspx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

音盲 2024-12-07 08:29:07

是的,如果闭包从本地范围(即本上下文中的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 对象(闭包),也是保存捕获变量的对象(转义变量记录)。

Yes, a lambda will create garbage if the closure captures a variable from the local scope (i.e. gameTime in this context).

For example, the following C# function:

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

Will get translated to this:

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));
}

Note that there are two instances of new in the resulting code, meaning that there is not only Action objects being allocated (the closures), but also objects to hold the captured variables (escaping variable records).

叹梦 2024-12-07 08:29:07

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

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

In this case I think that you are using a generic method (ForEach) which will generate a new type (assuming that Foo is a reference type, only one new type will be generated), and the lambda will be compiled as a regular anonymous method. Nothing about that suggests any sort of linear increase in memory usage.

As far as the profiler is concerned, you are not measuring anything about memory or the GC. You are measuring time spent executing the method, and the lambda should not be significantly slower than the 'regular' way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文