2014-10-14 24 views
20

Tôi đã đọc qua các nguồn NET khi tôi thấy điều này:NET địa phương biến tối ưu hóa

// Constructs a Decimal from an integer value. 
// 
public Decimal(int value) { 
    // JIT today can't inline methods that contains "starg" opcode. 
    // For more details, see DevDiv Bugs 81184: x86 JIT CQ: 
    // Removing the inline striction of "starg". 
    int value_copy = value; 
    if (value_copy >= 0) { 
     flags = 0; 
    } 
    else { 
     flags = SignMask; 
     value_copy = -value_copy; 
    } 
    lo = value_copy; 
    mid = 0; 
    hi = 0; 
} 

Như bạn có thể thấy, các nhà xây dựng các bản sao cấu trúc Decimal phương pháp luận cho một biến địa phương hơn là sử dụng nó trực tiếp. Tôi đã tự hỏi những gì bình luận có nghĩa là và làm thế nào nó có liên quan đến hiệu suất tối ưu hóa &?

Đoán của tôi là khi bạn muốn sửa đổi đối số hiện tại, phương pháp có thể không còn được nội tuyến?

http://referencesource.microsoft.com/#mscorlib/system/decimal.cs#f9a4da9d6e110054#references

Trả lời

15

tôi đoán là một khi bạn muốn sửa đổi các tham số hiện có, phương pháp có thể được không còn inlined?

Câu trả lời ngắn: đoán của bạn là chính xác (nếu đó là mã nguồn bình luận là vẫn đúng ngày hôm nay).

// JIT today can't inline methods that contains "starg" opcode. 

"Các JIT" là một phần của bộ thực thi .NET rằng dịch intermediate language (IL) (i.e. .NET "bytecode") sang ngôn ngữ lắp ráp máy tính của bạn. Chỉ sau đó có thể mã được thực hiện bởi máy tính của bạn. JIT thực hiện phương thức dịch theo phương thức này, và chỉ khi thực sự cần thiết: Bất cứ khi nào một phương thức được gọi lần đầu tiên, nó được biên dịch lần đầu thành ngôn ngữ assembly thực, "just-in-time" (JIT).

Trình biên dịch C# không tạo ngôn ngữ lắp ráp cho kiến ​​trúc máy tính của bạn ngay lập tức; thay vào đó, nó tạo ra intermediate language, là một loại ngôn ngữ lắp ráp cho một máy xếp chồng trừu tượng (được xác định trong ECMA 334 international standard).

Ví dụ, bài tập với một tham số (trong ví dụ của bạn: value) sẽ nhận được dịch bởi các biên dịch C# để một lệnh IL gọi starg ("cửa hàng để tranh luận").

Nhận xét về cơ bản nói rằng nếu phương pháp có chứa một bài tập như vậy (value = …), thì JIT hiện tại sẽ không thể "nội tuyến" được. "Inlining a method" có nghĩa là thay vì tạo lệnh gọi đến một phương thức (tức là lệnh nhánh đến một vị trí mã khác), JIT thay vào đó sẽ chèn toàn bộ cơ thể của phương thức vào nơi nó được gọi. Điều này thường được thực hiện để tối ưu hóa tốc độ thực thi, bởi vì không có nhánh/nhảy là cần thiết, và ngoài ra tôi giả định rằng không có khung ngăn xếp mới nào cũng phải được thiết lập.

Bằng cách gán cho biến cục bộ thay thế (value_copy = …), giới hạn này của JIT bị phá vỡ, bởi vì gán cho biến cục bộ gây ra lệnh IL khác nhau được tạo: stloc ("lưu vào biến cục bộ").

Xem thêm:

+1

nên về cơ bản câu trả lời của bạn cho câu hỏi mình là có. Tôi đã bắt đầu với điều đó và hơn là giải thích thêm. – Clueless

+1

câu trả lời hay ... –

+0

@Clueless: Cảm ơn bạn đã đề xuất! Tôi đã thêm một câu trả lời TL; DR. Tôi có xu hướng khó chịu đó để đưa ra những câu trả lời dài mà tôi không thể bỏ qua. :) – stakx