2010-05-16 8 views
6

Tôi có một phương thức trong C# cần trả về một mảng rất lớn (hoặc bất kỳ cấu trúc dữ liệu lớn nào khác cho vấn đề đó).C# Hàm bình thường trả về giá trị VS out hoặc ref argument

Có hiệu suất trong việc sử dụng thông số ref hoặc out thay vì giá trị trả về chuẩn không?

I.E. là có bất kỳ hiệu suất hoặc lợi ích khác trong việc sử dụng

void function(sometype input, ref largearray) 

qua

largearray function(sometype input) 
+0

Tôi nghĩ bạn đang bối rối; bạn sẽ trả về một tham chiếu đến một mảng lớn, không phải mảng đó ... –

+1

Stadard. Các mảng Net đã là các kiểu tham chiếu. – Dykam

Trả lời

5

Lượng ngăn xếp không gian sử dụng trên một bộ xử lý x86 32-bit để vượt qua đối số của các loại khác nhau:

  • byte: 4 byte
  • bool: 4 byte
  • enum: 4 byte
  • char: 4 byte
  • ngắn: 4 byte
  • int: 4 byte dài
  • : 8 b ytes
  • float: 4 byte
  • kép: 8 byte
  • thập phân: 16 byte
  • struct: kích thước thời gian chạy của cấu trúc

  • chuỗi: 4 byte
  • mảng: 4 byte
  • đối tượng: 4 byte
  • giao diện: 4 byte
  • con trỏ: 4 byte
  • lớp Ví dụ: 4 byte

Những người sống dưới mức nhiều loại tài liệu tham khảo, kích thước của chúng sẽ tăng gấp đôi vào một bộ xử lý 64-bit.

Đối với cuộc gọi phương thức tĩnh, 2 đối số đầu tiên có tối đa 4 byte sẽ được chuyển qua thanh ghi CPU chứ không phải ngăn xếp. Đối với một phương thức instance, chỉ một đối số sẽ được chuyển qua các thanh ghi. Phần còn lại được chuyển vào ngăn xếp. Bộ xử lý 64 bit hỗ trợ truyền 4 đối số thông qua thanh ghi.

Như được rõ ràng từ danh sách, thời gian duy nhất bạn nên xem xét việc chuyển một đối số bằng ref là dành cho cấu trúc. Hướng dẫn bình thường cho việc này là làm như vậy khi cấu trúc lớn hơn 16 byte. Nó không phải là luôn luôn dễ dàng để đoán kích thước thời gian chạy của một cấu trúc, lên đến 4 lĩnh vực thường sẽ được chính xác. Ít hơn nếu các trường đó là gấp đôi, dài hoặc thập phân. Hướng dẫn này sau đó thường khuyến khích chuyển cấu trúc của bạn thành một lớp học, chính xác vì lý do này.

Cũng lưu ý rằng có không có khoản tiết kiệm chuyển đối số dưới dạng byte hoặc ngắn cố ý, int là loại bộ xử lý 32 bit hài lòng. Tương tự cho các bộ vi xử lý 64-bit hiện có.


Giá trị trả về của phương thức, chủ đề thực sự của câu hỏi của bạn hầu như luôn được trả về trong thanh ghi CPU. Hầu hết các loại phù hợp thoải mái trong eax hoặc edx: đăng ký eax, một thanh ghi FPU cho các giá trị dấu phẩy động. Ngoại lệ duy nhất là cấu trúc lớn và số thập phân, chúng quá lớn để vừa với thanh ghi. Chúng được gọi bằng cách đặt không gian trên ngăn xếp cho giá trị trả về và chuyển một con trỏ 4 byte đến không gian đó làm đối số cho phương thức.

+0

Đây là câu trả lời tôi đang tìm kiếm.Tôi không thể nhìn thấy làm thế nào để gắn cờ này như là một câu trả lời mặc dù - Tôi là một newbie và tôi hơi mù có lẽ? – user335023

1

Một tham số out trả về một tham chiếu đến một thể hiện của loại, mà đã không yêu cầu phải được khởi tạo trước khi gửi vào một phương pháp.

Một tham số ref trả về một tham chiếu đến một thể hiện của loại, rằng phải được khởi tạo trước khi gửi vào một phương pháp.

Đây là về ngữ nghĩa cuộc gọi, KHÔNG hiệu suất.

1

Không có, chỉ trả lại mảng

1

Sẽ không có sự khác biệt giữa

void function(sometype input, out largearray output) 

qua

largearray function(sometype input) 

Tuy nhiên, nếu bạn làm

largearray function(sometype input, ref largearray output) 

và bạn yêu cầu e người gọi đã được phân bổ trước mảng lớn, điều đó tất nhiên sẽ nhanh hơn, nhưng nó sẽ chỉ quan trọng nếu bạn gọi phương thức lặp đi lặp lại và giữ mảng lớn được phân bổ giữa các cuộc gọi.