2010-10-21 17 views
5

Tôi thấy một số câu hỏi liên quan đến việc tối ưu hóa cuộc gọi đuôi bị thiếu trong C# được cho là làm cho ngôn ngữ không phù hợp với việc triển khai thuật toán đệ quy. tuy nhiên, điều này đặt ra câu hỏi, làm thế nào chúng ta có thể thực hiện tối ưu hóa cuộc gọi đuôi và vẫn cung cấp dấu vết ngăn xếp hợp lý khi ngoại lệ được nâng lên hoặc khi sự phản chiếu có thể được sử dụng để kiểm tra ngăn xếp cuộc gọi và hành động theo nó.Làm thế nào để tối ưu hóa đệ quy C# có thể được trả lại khi một ngoại lệ được nâng lên

Trả lời

5

Vâng, nó chỉ vấn đề nếu bạn mong đợi để có được một stack trace chính xác :)

Tail gọi tối ưu hóa không phải là điều duy nhất có thể phá hủy một stack trace - ví dụ đơn giản nhất là nội tuyến, mà có thể chắc chắn ảnh hưởng đến mọi thứ. Về cơ bản, bất cứ thứ gì dựa vào dấu vết ngăn xếp chính xác đều có một chút rủi ro.

Dưới đây là một ví dụ rất đơn giản chính xác vấn đề rằng:

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(); 
    } 
} 

xây dựng và chạy mà không cần trình gỡ lỗi, và bạn có thể có được điều này:

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

Về cơ bản, hãy cẩn thận những gì bạn làm với chồng dấu vết.

+1

các thông báo lỗi chắc chắn mà tôi xử lý hàng ngày từ người dùng có dấu vết ngăn xếp chính xác mặc dù bất kỳ trình tối ưu hóa trình biên dịch nào. Tôi không chắc chắn sẽ hoàn thành nhiều việc :-) –

+1

@Carlo: Đó có thể là do dấu vết ngăn xếp của người dùng nằm trong đường dẫn không bao gồm nội tuyến hoặc tối ưu hóa cuộc gọi đuôi. Ngoài ra, tôi mạnh mẽ nghi ngờ rằng nếu bạn nhìn thực sự cẩn thận, đôi khi bạn sẽ thấy dấu vết ngăn xếp * không * chính xác trong mọi khung hình - nhưng chỉ chính xác trong các khung mà bạn quan tâm. –

Các vấn đề liên quan