2016-12-31 4 views
12

Мы используем рекурсию для поиска факторов и получаем исключение StackOverflow. Мы читали, что the C# compiler on x64 computers performs tail call optimizations:Почему оптимизация вызовов хвоста не встречается здесь?

JIT определенно делает tailcals при запуске оптимизированного кода, а не отладки.

Запуск dotnet --configuration release получает далеко в нашей программе:

...      
7214 is a factor of 1234567890 
7606 is a factor of 1234567890 
10821 is a factor of 1234567890 
11409 is a factor of 1234567890     

Process is terminated due to StackOverflowException. 

Почему оптимизация хвост вызов не встречающийся?

class Program 
{ 
    static void Main(string[] args) 
    { 
     const long firstCandidate = 1; 
     WriteAllFactors(1234567890, firstCandidate); 
    } 

    private static void WriteAllFactors(long number, long candidate) 
    { 
     if (number % candidate == 0) 
     { 
      System.Console.WriteLine($"{candidate} is a factor of {number}"); 
     } 

     candidate = candidate + 1; 
     if(candidate > number/2) 
     { 
      return; 
     } 

     WriteAllFactors(number, candidate); 
    } 
} 
+1

Не требует возврата хвостового вызова, чтобы вернуть значение? – zzzzBov

+0

@zzzzBov Я предполагаю, что это риторический вопрос. :) –

+1

Нет возврата вообще; что мешает этому бежать вечно? –

ответ

3

VSadov обеспечивает явную причину этого в своем ответе:

Вообще JIT испускает хвост вызовов, когда он приходит к выводу, что выгодно.

Кроме того, он продолжает утверждать:

Это та часть, которая не выражается в C#. В отличие от inlining, который может быть принудительно с помощью атрибутов, tailcalling в настоящее время не может быть принудительно. Если вам нужно написать код, похожий на EmitMethodCall, он не может использовать C#.

Таким образом, ответ заключается в том, что, хотя хвосты определенно доступны и используются, нет никакого способа предсказать, когда они будут использоваться или заставить их использоваться на C#.

+0

Я удивлен, что предотвратить исключение StackOverflow не выгодно. Если это ответ, тогда это ответ. –

 Смежные вопросы

  • Нет связанных вопросов^_^