2010-10-21 9 views
5

Ho visto alcune domande relative all'ottimizzazione della coda mancante in C# che presumibilmente rendono il linguaggio non adatto alle implementazioni di algoritmi ricorsivi. questo, tuttavia, pone la domanda, come possiamo fare ottimizzazioni di coda e fornire ancora tracce di stack sensibili quando vengono sollevate eccezioni o quando può essere usato il reflection per ispezionare lo stack di chiamate e agire su di esso.come è possibile l'ottimizzazione della ricorsione su coda C# quando viene restituita una traccia stack quando viene sollevata un'eccezione

risposta

5

Beh, unicamente le questioni se si aspettano di ottenere un accurato dello stack :)

ottimizzazioni coda di guardia non sono le uniche cose che possono distruggere una traccia dello stack - l'esempio più semplice è messa in linea, che può certamente influenzare le cose Fondamentalmente, tutto ciò che si basa sulla traccia dello stack è accurato sta prendendo un po 'di rischio.

Ecco un esempio molto semplice di esattamente questo problema:

using System; 
using System.Runtime.CompilerServices; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      Call1(); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.StackTrace); 
     } 
    } 

    static void Call1() 
    { 
     Call2(); 
    } 

    static void Call2() 
    { 
     Call3(); 
    } 

    [MethodImpl(MethodImplOptions.NoInlining)] 
    static void Call3() 
    { 
     Call4(); 
    } 

    static void Call4() 
    { 
     Call5(); 
    } 

    static void Call5() 
    { 
     throw new Exception(); 
    } 
} 

Compilare ed eseguire senza il debugger, e si può ottenere questo:

at Program.Call3() 
at Program.Main(String[] args) 

In sostanza, essere attenti a quello che fate con pila tracce.

+1

messaggi di errore con cui mi occupo quotidianamente dagli utenti ha una traccia di stack accurata nonostante eventuali ottimizzazioni del compilatore.altrimenti non sono sicuro che si ottenga molto :-) –

+1

@Carlo: probabilmente perché le tracce dello stack dagli utenti tendono essere in percorsi che non includono l'inlining o l'ottimizzazione di tail-call. Inoltre, sospetto fortemente che se guardi con attenzione, occasionalmente vedrai tracce di stack che * non sono * accurate in ogni fotogramma - ma sono solo accurate nei fotogrammi che ti interessano. –