C# Does Lambda => generate garbage?

Napoleon picture Napoleon · Aug 20, 2011 · Viewed 10.3k times · Source

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

Answer

Gabe picture Gabe · Aug 20, 2011

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).