2011-11-21 16 views
11

Gần đây tôi đã thực hiện một số phép đo hiệu suất thô trên List<>[] cho một loạt các cấu trúc nhỏ. System.Array dường như giành chiến thắng tay vì vậy tôi đã đi với điều đó.System.Array có thực hiện quyền anh trên các loại giá trị hay không?

Nó chỉ làm tôi ngạc nhiên rằng System.Array chứa các loại đối tượng, vì vậy chắc chắn làm đầy nó với cấu trúc sẽ gây ra boxing xảy ra?

Tuy nhiên, the MSDN entry for System.Array trạng thái:

Trong phiên bản .NET Framework 2.0, lớp Array thực hiện các System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T>, và System.Collections.Generic.IEnumerable<T> giao diện chung. Việc triển khai được cung cấp cho các mảng tại thời gian chạy và do đó, không hiển thị với các công cụ xây dựng tài liệu. Do đó, các giao diện chung không xuất hiện trong cú pháp khai báo cho lớp Array và không có chủ đề tham chiếu nào cho các thành viên giao diện chỉ có thể truy cập được bằng cách truyền mảng đến loại giao diện chung (triển khai giao diện rõ ràng) .

Điều này có nghĩa là quyền anh không xảy ra sau tất cả? (Và sẽ giải thích kết quả hiệu suất của tôi)

+0

Để giải thích kết quả hiệu suất của bạn, có lẽ chúng ta sẽ thấy mã bạn đã sử dụng để đo lường hiệu suất. – Snowbear

Trả lời

12

Không sử dụng mảng không có hộp nếu bạn sử dụng ký pháp chỉ mục. ví dụ:

new int[2]; 
x=[1]=3; 

Biên dịch sang IL sau (chú ý số dòng không liên quan như họ đến từ một số đoạn khác của mã)

IL_0011: ldc.i4.2 
IL_0012: newarr System.Int32 
IL_0017: stfld Int32[] x 
IL_001c: ldarg.0 
IL_001d: ldfld Int32[] x 
IL_0022: ldc.i4.1 
IL_0023: ldc.i4.3 
IL_0024: stelem.i4 

Đối với các ngôn ngữ mà không thể sử dụng các Indexer (và tôi không thực sự biết nếu chúng tồn tại hay không) 2 phương pháp khác được tạo ra tại thời gian biên dịch cho mảng.

Nó tạo ra những phương pháp công cộng ::

public int Get(int index) 
public void Set(int index,int value) 

Những phương pháp này không hộp hoặc và thường không truy cập thông qua C#. (Đừng hỏi tôi tại sao họ là phương pháp công cộng). Bạn có thể thực hiện chúng bằng cách sử dụng IL hoặc bằng cách tạo các đại biểu cho chúng. Chúng chậm hơn khi bạn buộc phải thực hiện một cuộc gọi để gọi các phương thức này.

Gia đình stelem. * Và ldelem. * Được sử dụng để xử lý lưu trữ cho loại mảng được nhập mạnh mẽ. Khi sử dụng generics thường các tiền tố sau được đính kèm constrained hoặc readonly khi sử dụng T[]. stelem.* loại thường không kiểm tra loại. Ví dụ. sử dụng stelem.i4 nhanh hơn sử dụng stelem.any Int32 trừ khi bạn thêm tiền tố với readonly vì nếu không, nó sẽ kiểm tra loại.

Bây giờ typecheck là hoàn toàn vô dụng trên mảng valuetype là chúng không phải là biến thể!

Vì thời gian chạy tạo mảng một chiều bắt đầu từ số không (hoặc được gọi là loại SZ_array hoặc loại véc tơ), chúng được biết nguyên gốc.

Có một gia đình mã op il cho họ: newarr, stelem.*, ldelem.*, ldlen, vv

Loại List<T> sử dụng một T[] cho cửa hàng ủng hộ mình trong việc thực hiện microsoft của BCL. List<T> không hộp. Bất kể việc sử dụng danh sách hoặc mảng bạn đang lưu trữ mọi thứ trong một mảng.

+1

Đây là một liên kết bổ sung cho câu trả lời khác liên quan đến phân bổ heap/stack của mảng và giá trị chứa của chúng: http://stackoverflow.com/questions/1113819/arrays-heap-and-stack-and-value-types/1114152#1114152 – BoltClock

+1

Vì mảng là các kiểu tham chiếu, các int không được lưu trữ cũng được lưu trữ trong vùng được quản lý - không có gì để đánh dấu. – Alex

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