Согласно «Эксперту F #», написанному доном Симом и др., F # делает оптимизацию хвостовых вызовов. Кажется, я помню, как читал блог Эрика Липперта, что компилятор C# (любая версия) этого не делает. Поправьте меня, если я ошибаюсь, Эрик. Во всех случаях оптимизации хвостового вызова могут выполняться, когда последняя команда должна вызывать метод. Это часто будет рекурсивным вызовом самого метода, но не обязательно. Оптимизация может быть выполнена, поскольку гарантируется, что текущий стек стека больше не нужен. Однако, если после выполнения просто выполнить операцию, оптимизация не может быть выполнена.
int Fib(int n)
{
if(n < 2)
return 1;
return Fib(n-1) + Fib(n-2);
}
Это не может быть хвост вызов оптимизирован, потому что +
не может быть оценена до последнего вызова Fib
возвращается. (На самом деле я думаю, что это пример, используемый в Expert F #, как хорошо, но не уверен в том, что один.)
int Fib(int n, int a, int b)
{
if(n == 0)
return a+b;
return Fib(n-1,a+b,a);
}
Эта версия может быть хвост вызова оптимизирован, так как все аргументы оцениваются до того последний вызов Fib и никакие операции не выполняются после вызова, поэтому текущий стек стека может быть отброшен.
Эрик Липперт, где ты? – SLaks
Что именно вы ищете? Правда или самый популярный ответ? Здесь доступны только последние. –
Его просьба о предоставлении доказательств («надежные, современные источники или воспроизводимые эксперименты») показала бы, что он ищет «правду». Независимо от того, как вы относитесь к SO, его вопрос действителен, поскольку компилятор .NET и CLR фактически детерминированы. Кто-нибудь сможет раскрыть эту истину, все еще в воздухе. – jball