C # Lambda => генерирует мусор? - PullRequest
23 голосов
/ 20 августа 2011

Создает ли лямбда-выражение мусор для GC, в отличие от обычного цикла foreach?

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

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

CLR-профилировщик показывает, что у меня 69,9% system.Action , и я подозреваю, что этоЛамба версия цикла foreach, как указано выше.Это правда?

РЕДАКТИРОВАТЬ: Я использовал профилировщик Microsoft CLR: http://download.microsoft.com/download/4/4/2/442d67c7-a1c1-4884-9715-803a7b485b82/clr%20profiler.exe или http://msdn.microsoft.com/en-us/library/ff650691.aspx

Ответы [ 2 ]

22 голосов
/ 20 августа 2011

Да, лямбда будет создавать мусор, если замыкание захватывает переменную из локальной области (т. Е. gameTime в этом контексте).

Например, следующая функция 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 объекты (замыкания), но и объекты для хранения захваченных переменных ( экранирование переменных записей).

0 голосов
/ 20 августа 2011

В этом случае я думаю, что вы используете универсальный метод (ForEach), который сгенерирует новый тип (при условии, что Foo является ссылочным типом, будет сгенерирован только один новый тип), и лямбда будет скомпилирована какобычный анонимный метод.Ничто об этом не предполагает какого-либо линейного увеличения использования памяти.

Что касается профилировщика, вы ничего не измеряете в памяти или в ГХ.Вы измеряете время, потраченное на выполнение метода, и лямбда не должна быть значительно медленнее, чем «обычный» способ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...