Arent замыкания предлагают выделить? - PullRequest
3 голосов
/ 07 ноября 2019

Я всегда работал с точки зрения, что замыкания создают распределение, и его следует избегать из критического кода. Является ли эта точка зрения устаревшей?

enter image description here

using System;

public class Foo
{
    private Random rand = new Random();

    private static int Get(Func<int> factory)
    {
        return factory() + 1;
    }

    public void Test()
    {
        Console.WriteLine("foobar");

        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();

        float foo = 1f;

        for (int i = 0; i < 100000; i++)
        {
            foo += DoTestRun();
        }
    }

    private float DoTestRun()
    {
        var j = rand.Next(0, 100);
        return Get(() => j + 5);
    }
}
class Program
{
    static void Main()
    {
        new Foo().Test();
    }
}

1 Ответ

4 голосов
/ 07 ноября 2019

Да, они выделяют;вот верхняя часть отладчика выделения в devenv:

Name    Total (Allocations) Total Size (Bytes)
 + System.Func`1    100002  6400128
| + [Native]    100002  6400128
|| + Program::Main  100002  6400128
||| + Foo::Test 100002  6400128
|||| - Foo::DoTestRun   51190   3276160
|||| - Foo::DoTestRun   48810   3123840
|||| - System.Console.WriteLine(System.String)  2   128
 + Foo.<>c__DisplayClass3_0 100000  2400000
| + [Native]    100000  2400000
|| + Program::Main  100000  2400000
||| + Foo::Test 100000  2400000
|||| - Foo::DoTestRun   51190   1228560
|||| - Foo::DoTestRun   48810   1171440

Это делегаты и экземпляры контекста захвата из Get(() => j + 5). Так что да, это выделяет. Является ли это катастрофическим для вашего сценария: многое зависит от вашего сценария.

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