2011-01-26 18 views
14

Tôi biết rằng boxing and unboxing are relatively expensive về hiệu suất. Điều tôi đang tự hỏi là:Việc chuyển một loại giá trị trong tham số "ngoài" có khiến biến được đóng hộp không?

Không chuyển một loại giá trị sang tham số out của phương thức gây ra sự cố/unboxing biến (và do đó có hiệu suất đạt được)? Trình biên dịch có thể tối ưu hóa điều này không?

int number; 
    bool result = Int32.TryParse(value, out number); 
+0

Tra cứu tối ưu hóa sớm. Phân tích cú pháp một số nguyên (phân tích cú pháp nói chung) là cách, tốn kém hơn nhiều so với một thao tác boxing đơn giản. – Dykam

+0

@Dykam: Đúng vậy. Tôi chỉ sử dụng 'TryParse' làm ví dụ. –

Trả lời

18

Như những người khác đã chỉ ra, không có quyền anh ở đây. Khi bạn chuyển một biến làm đối số tương ứng với tham số out hoặc ref, những gì bạn đang làm là tạo bí danh cho biến số. Bạn không làm bất cứ điều gì với giá trị của biến. Bạn đang tạo hai biến đại diện cho cùng một vị trí lưu trữ.

Quyền anh chỉ xảy ra khi giá trị của loại giá trị được chuyển đổi thành giá trị của loại tham chiếu và không có chuyển đổi dưới bất kỳ hình thức nào trong ví dụ của bạn. Loại tham chiếu phải dĩ nhiên là System.Object, System.ValueType, System.Enum hoặc bất kỳ giao diện nào. Thông thường nó là khá rõ ràng; có một chuyển đổi rõ ràng hoặc tiềm ẩn trong mã. Tuy nhiên, có thể có những hoàn cảnh ít rõ ràng hơn. Ví dụ, khi một phương thức ảo không được ghi đè của kiểu cơ sở của cấu trúc được gọi, có quyền đấm. (Cũng có những tình huống kỳ lạ trong đó một số loại ràng buộc kiểu chung nhất định có thể gây ra việc đấm bốc bất ngờ, nhưng chúng thường không xuất hiện trong thực tế.)

+0

Cảm ơn câu trả lời. Vẫn còn một hit hiệu suất liên quan? Làm thế nào để so sánh với các lần truy cập từ quyền anh/unboxing, chuyển một loại tham chiếu hoặc chuyển một loại giá trị? –

+6

@Justin: Lời khuyên tốt nhất cho bất kỳ câu hỏi hiệu suất nào: ** hãy thử nó và bạn sẽ tìm ra **. Những gì bạn có thể tìm thấy là thường truyền một biến bằng tham chiếu là cùng một chi phí khi chuyển một tham chiếu đến một thể hiện của một kiểu tham chiếu bằng tham chiếu, có cùng chi phí khi chuyển một kiểu giá trị của kích thước IntPtr. Hãy nhớ rằng việc truyền tham số có kích thước con trỏ có thể được tối ưu hóa rất nhiều bởi jitter nếu có các thanh ghi có sẵn. –

5

Không, không có quyền Anh (bắt buộc/tham gia).

Khi bạn thực hiện biến Box, thay đổi đối với cá thể đã đóng hộp không ảnh hưởng đến bản gốc. Nhưng đó là chính xác những gì out là nghĩa vụ phải làm.

Trình biên dịch 'bằng cách nào đó' xây dựng một tham chiếu đến biến ban đầu.

+0

Cảm ơn câu trả lời. Bạn có biết nếu vẫn còn một hit hiệu suất liên quan? Làm thế nào để nó so sánh với hit từ boxing/unboxing, hoặc để đi qua các thông số bình thường? –

+1

@Justin, chi phí sẽ phụ thuộc vào hoàn cảnh (trường hoặc var cục bộ) nhưng đối với một 'cục bộ' cục bộ có thể sẽ là nhanh nhất. Bạn sẽ phải đo lường tình huống _your_. Nhưng nó là một tối ưu hóa vi mô tốt nhất và không có lựa chọn thay thế thực sự. –

1

Không có quyền anh; thông số out là chỉ định số đó phải được gán cho trong phương thức TryParse. Bất kể điều này, nó vẫn được coi là int, không phải là object.

6

Không có quyền anh, trình biên dịch sử dụng lệnh ldloca.s đẩy tham chiếu đến biến cục bộ lên ngăn xếp (http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes. ldloca_s (VS.71) .aspx)

.method private hidebysig static void Func() cil managed 
{ 
    .maxstack 2 
    .locals init (
     [0] int32 num, 
     [1] bool flag) 
    L_0000: nop 
    L_0001: ldstr "5" 
    L_0006: ldloca.s num 
    L_0008: call bool [mscorlib]System.Int32::TryParse(string, int32&) 
    L_000d: stloc.1 
    L_000e: ret 
}