На этот вопрос есть ответы на многих уровнях, и я боюсь, что вы не получите действительно 100% точный, но здесь идет.
Здесь есть две разные части памяти, на которых я хочу сосредоточиться:
- Память, выделенная для хранения кода
- Память, выделенная на код
Первый фрагмент выделяется JITter, и это определенно связано с количеством кода в методе. Однако, если вы решите распространить этот метод на несколько методов (что следует делать, метод не должен быть длиной в тысячу строк, не говоря уже о 50), то вы также распределите память по этим методам. На самом деле, вероятно, существует определенное количество служебных данных для каждого метода, поэтому в этом случае может оказаться, что для кода JITted будет использовано больше памяти, если вы будете использовать больше методов, чем один большой, но это не имеет значения. Разделите это. Серьезно.
Второй фрагмент памяти - это то, что код выделяет при выполнении. Это, конечно, полностью зависит от того, что делает код, поэтому нельзя сказать, что один метод лучше другого, если судить только по количеству строк. 1000-строчный метод может не выделить много, тогда как однострочный метод может выделить много. Там нет никакого способа узнать, кроме как путем изучения фактического кода.
Кроме того, в сборке режима выпуска, работающей вне отладчика, сборщик мусора очень агрессивен, поэтому переменная, объявленная в верхней части метода, заполненная структурой данных, а затем в методе не используется больше GC может потребовать это, так как он имеет вид с высоты птичьего полета вашего кода. Он может «видеть», что переменная больше не используется, поэтому можно просто собрать все, что в ней есть.
Однако во время отладки срок жизни этой переменной искусственно увеличивается до конца области действия / метода, поэтому, если вы остановите программу где-то в той части кода, где переменная больше не используется, вы можете еще осмотрите его содержимое.
Итак, подытожим:
- Более длинный метод, вероятно, потребует больше памяти JITted, чем более короткий метод, но если вы не можете фактически удалить код, в отличие от простого его перемещения и разделения, он не имеет значения. Пишите короткие методы.
- Память, выделенная методом, связана не с количеством строк, а с содержанием этих строк.
Теперь, что касается System.Func<T...>
, это просто указатель на небольшой объект. Размер этого объекта будет зависеть от количества аргументов (если я правильно помню) функции / метода, на которую он ссылается, но в остальном он не зависит от размера метода, кода или выделения памяти или чего-то еще.
Как указывает @Marc, делегат в .NET поддерживает многоадресную рассылку. Это решается с помощью цепочки объектов, поэтому используемая память также будет зависеть от количества элементов в этой цепочке.
Не беспокойтесь об использовании делегатов. Они довольно дешевы, как с точки зрения процессора, так и с точки зрения памяти.