Здравствуйте, Эйнсток Файр, Вы писали:
S>> Даже если мы в цикле вызываем один и тот же метод.
ЭФ>Мне же предлагали про циклы подумать. Где циклы, там муть (mut). Значит и место для всех вызовов подпрограмм можно заранее рассчитать и выделить.
Ок, давайте разовьём вашу мысль.
1. "Заранее рассчитать и выделить" — то есть вы предполагаете, что мы выделяем не один фрейм, а сразу блок (сегмент). Это один из подвариантов варианта 3. С его недостатками — в частности, сама функция не может знать, вызывают ли её в цикле, т.е. не выделен ли ей заранее целый сегмент. Значит, её пролог будет довольно сложно устроен — надо сравнить её потребности в стеке с остатком места в текущем сегменте стека, и в зависимости от этого либо просто инкрементировать стек-поинтер, либо выделять в куче новый сегмент. При этом опять же, при выходе из этой функции выделенный ею сегмент будет гарантированно больше не нужен, то есть мы должны его как-то "освободить", и на следующей итерации придётся заново выделять ещё один такой же сегмент.
2. Давайте теперь поговорим про саму возможность рассчитать заранее вызовы всех подпрограмм.
Рассмотрим простейший код, который подсчитывает количество листьев у дерева:
public int Count<T>(this T root) where T:IEnumerable<T>
{
int c = 0;
foreach(var child in root) // вот он цикл
c += // вот она муть
Count(child); // вот он вызов подпрограммы
return c;
}
сколько места вы заложите на "все вызовы подпрограмм"?